<< Autoboxing This | Home | 1.03 - .42 = 0.6100000000000001? No Way! >>

1.03 - .42 = ?

Item 31 of Joshua Bloch's Effective Java reads:

Avoid float and double if exact answers are required

And as an example, he used the following example:

System.out.println(1.03 - .42);

which prints

0.6100000000000001

I understand the reasoning behind the advice. No problem there.

Out of curiosity, I tried similar expressions in several different languages that's available on my Fedora Core 2 box. And the result is fascinating:

LanguageExpressionResult
C# Console.WriteLine(1.03 - .42); 0.61
C++ std::cout << 1.03 - 0.42 << std::endl; 0.61
Perl print(1.03 - .42); 0.61
Python print(1.03 - .42) 0.61
Ruby print(1.03 - 0.42) 0.61
Guile (display (- 1.03 .42)) 0.61

What is going on here?



Re: 1.03 - .42 = ?

And in Groovy:

println 1.03 - 0.42

will also print 0.61.

Re: 1.03 - .42 = ?

The problem is in the printing, not in the precision (at least for C++ and for C# as well, I assume). They are not printing the full precision of the answer but rather a fixed set of decimal points (maybe the first 6 or 7).

Re: 1.03 - .42 = ?

Try thi s bit of Ruby: n = 1.03 - 0.42 puts n puts n == 0.61

Re: 1.03 - .42 = ?

It took away my CRs: n = 1.03 - 0.42; puts n; puts n == 0.61

Re: 1.03 - .42 = ?

Weiqi, a Ph.D. Mathemetician, knows the answer already, but I will humor him. <p/> There are two problems here. One problem is that computer representation of real numbers is only approximate. Certain real numbers cannot be represented in binary floating-point arithmetic, for example, 1/5. The non-Java implementations are simply displaying fewer digits of the answer. <p/> The second problem is that significant digit discipline is not observed by the Java programmer, because of the default formatting used in the floating-point to String conversion. A decent explanation of this is found at mathworld <p/> I highly recommend that every Java developer buy and read Java Number Cruncher: The Java Programmer's Guide to Numerical Computing by Ronald Mak ISBN 0-13-046041-9. <p/> Also of note is work that is in progress to enhance the IEEE 754 spec with decimal floating-point math. This is in the works for Java in BigDecimal in 1.5 (or J2SE v5, or whatever it's called this week). It is also in the works for other languages. This will improve computer representation of decimal real numbers.

Add a comment Send a TrackBack