If the double type can handle the numbers 4.35 and 435, why do 4.35 * 100 evaluates to 434.99999999999994?

floating-point, java, math, printing, string

Solution

Seems that in binary both 4.35 and 435 can be represented with exactitude.

I see that you understand how the floating point numbers are internally represented. As for your doubt, no `4.35` does not have an exact binary representation. So the issue is, why the 1st print statement prints `4.35`.

That is happening because `System.out.println()` invokes the `Double.toString(double)` method, which in turns uses `FloatingDecimal#toJavaFormatString()` method, which performs some rounding internally on the passed double argument. You can go through the source code I linked.

For seeing the actual value of `4.35`, try using this:

BigDecimal bd = new BigDecimal(number1);
System.out.println(bd);

This will print:

4.3499999999999996447286321199499070644378662109375

In this case, rather than printing the double value, you create a `BigDecimal` object passing `double` value as argument. `BigDecimal` represents arbitrary precision signed decimal number. So it gives you the exact value of `4.35`.

Problem

As I understand this, some numbers can't be represented with exactitude in binary, and that's why floating-point arithmetic sometimes gives us unexpected results; like 4.35 * 100 = 434.99999999999994. Something similar to what happens with 1/3 in decimal. That makes sense, but this induces another question. Seems that in binary both 4.35 and 435 can be represented with exactitude. That's when it stops making sense to me. Why does 4.35 * 100 evaluates to 434.99999999999994? 435 and 4.35 have an exact representation in the double type dynamics: ``` double number1 = 4.35; double number2 = 435; double number3 = 100; System.out.println(number1); // 4.35 System.out.println(number2); // 435.0 System.out.println(number3); // 100.0 // So far so good. Everything ok. System.out.println(number1 * number3); // 434.99999999999994 !!! // But 4.35 * 100 evaluates to 434.99999999999994 ``` Why? Edit: this question was marked as duplicate, and it is not. As you can see in the accepted answer, my confusion was regarding the discrepancy between the actual value and the printed value.

Original source

Related problems