views:

696

answers:

6

When I type this into the Visual Studio 2008 immediate window:

? .9 - .8999999999999995

It gives me this as the answer:

0.00000000000000055511151231257827

The documentation says that a double has 15-16 digits of precision, but it's giving me a result with 32 digits of precision. Where is all that extra precision coming from?

+14  A: 

The leading zeros are not significant/part of the precision (as far as the floating point number is concerned -- mathematically speaking, they are significant). The leading zeros are due to the exponent part of the floating point number's internal representation.

The portion 55511151231257827 (which is the significand or mantissa) has 17 decimal digits, which is close enough to 15-16 digits.

@Lars D: What you consider to be correct, is only correct within the context of the question. .9 - .8999999999999995 works out to a float with significand 0.625 and exponent of -50. Taking 0.625 * 2-50 results in 5.5511151231257827e-16. Now, out of the context of the original question, we have a number with 17 significant digits which does happen to be our best binary approximation of 0.0000000000000005. However, those leading zeros are still not significant as far as the representation of the floating point number is concerned.

Mark Rushakoff
I downvoted this answer, because I consider your answer incorrect. The 15-16 digits precision in the actual subtraction operation give 0.0000000000000005, and the rest of the digits are random rounding errors. Therefore, in the 55511151231257827 part, there is only 1 correct digit, and the rest are rounding errors, that have been promoted into the mantissa because of the leading zeroes.Basically the 32 digits are 16 significant digits from the subtraction, plus 16 digits of noise in the mantissa afterwards. The zeroes only become insignificant AFTERWARDS, when the result is stored.
Lars D
Right - if I were taking chemistry again, the leading zeros *would* be significant digits. However, the computer has no concept of whether the zeros should be significant, and that is why there are approximately 16 *non-zero* digits represented in the answer.
Mark Rushakoff
A: 

I think its because in the binary system, 5 is periodic as it is not dividable by 2. And then what Mark Rushakoff said applies.

eWolf
+3  A: 

? .9 - .8999999999999995

This subtraction process, with 15-16 significant digits, gives

0.0000000000000005

The rest of the digits are just rounding errors. However, since the computer always stores 15-16 significant digits after the first non-zero digit, the rounding errors are shown, and you get a lot of trailing random digits produced by rounding errors. So the result has 16 significant digits from the subtraction operation plus 16 digits from the storage of the result, which gives 32 digits.

Lars D
+16  A: 

You should read: What Every Computer Scientist Should Know About Floating-Point Arithmetic .

Basically it comes down to Floating Point numbers being stored with finite precision. You have to do your comparison with some delta.

if(.9 - .8999999999999995 <= 0.0001)
  //close enough to be equal
Lolindrath
+1: It is a shame that SO cannot auto-answer with this for each and every floating point question, being the right answer for at least 90% of floating point questions.
Richard
this doesn't address his question on precision.
Ape-inago
-1, does not answer the question. The q is about 32 digits (not 16) for a double.
Henk Holterman
You didn't read the question.
raven
+3  A: 

The "floating" part of "floating point" means that you are getting something closer to 5.5511151231257827 * 10^(-16). That's not exactly how it's represented, because of course it's all done in binary under the hood, but the point is, the number is represented by the significant digits, plus a number which represents how far to move the radix (decimal point). As always, wikipedia can give you more detail:

(The second link is more specifically focused on your particular case.)

jcdyer
+40  A: 
Barry Brown
+1 for the leading zeroes explanation.
Paggas
+1 for explanation and the use of the word "mantissa"!
David Robbins
Where are all those other digits being stored?
Barry Brown
Not, it is the decimal representation of a binary point number. Including it's rounding errors.
Dykam
Wrong: "Leading zeroes don't count" is incorrect. The 15-16 important digits in the answer are 0.0000000000000005. The digits after that are incorrect, and are only present because the rounding errors are promoted into the mantissa because of the leading zeroes. As Barry wrote himself in his edit, the result is stored as 1.25*2^(-51)=5.551*10^(-16), which is a number that has 1 decimal digit of calculation accuracy, but is has 15-16 digits of storage precision.
Lars D
+1 for the cool converter.
pierr