5

Why does this assertion fail?

import std.conv;

void main()
{
    auto y = 0.6, delta=0.1;
    auto r = to!int(y/delta);
    assert(r == 6);
}

r's value should be 6 and yet it's 5, Why?

Algo
  • 841
  • 1
  • 14
  • 26
  • 3
    [Is floating point math broken?](http://stackoverflow.com/questions/588004/is-floating-point-math-broken) [What Every Programmer Should Know About Floating-Point Arithmetic](http://floating-point-gui.de/) – phuclv Dec 26 '14 at 11:00
  • 2
    after that read this thorough article [What Every Computer Scientist Should Know About Floating-Point Arithmetic](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – phuclv Dec 26 '14 at 11:01

2 Answers2

5

This is probably because 0.6 can't be represented purely in a floating point number. You write 0.6, but that's not exactly what you get - you get something like 0.599999999. When you divide that by 0.1, you get something like 5.99999999, which converts to an integer of 5 (by rounding down).

Examples in other languages:

C#: Why is (double)0.6f > (double)(6/10f)?

Java: Can someone please explain me that in java why 0.6 is <0.6f but 0.7is >=0.7f

Community
  • 1
  • 1
Range vs. Range
  • 325
  • 1
  • 3
  • 11
  • 1
    How can I round up then? – Algo Dec 26 '14 at 07:31
  • 2
    You can round to the nearest integer with std.math.round: http://dlang.org/library/std/math/round.html. If you know your floating point result is within 0.5 of the integer you want, this will round the result to what you want. Two answers for the price of one! – Range vs. Range Dec 26 '14 at 07:33
  • Or by adding 0.5. I.e use (y/delta+0.5) – runec Jan 02 '15 at 12:46
4

Computers represent floating point numbers in binary. The decimal numbers 0.6 and 0.1 do not have an exact binary representation, while number of bits used to represent them is finite. As a result, there would be truncation, whose effect is seen during division. The result of that division is not exactly 6.00000000, but perhaps 5.99999999, which is then truncated to 5.

Masked Man
  • 1
  • 7
  • 40
  • 80