can somebody explain in a understandable way this result

T

Tony Johansson

Hello!

Can somebody explain why I get 1.0000000149011612 when doing this expression
calculation ?
double d = 0.2f + 0.2f + 0.2f + 0.2f + 0.2f;
I know how to fix it that is not the question is about.
I now that a double have more then double as many significant number then a
float but can't
still understand the result.
If I instead change the type of d to float I get the expected result of 1.0.
I can also change the type of 0.2 to a double which also give the correct
result of 1.0

//Tony
 
A

Andrew Poelstra

Hello!

Can somebody explain why I get 1.0000000149011612 when doing this expression
calculation ?
double d = 0.2f + 0.2f + 0.2f + 0.2f + 0.2f;
I know how to fix it that is not the question is about.
I now that a double have more then double as many significant number then a
float but can't
still understand the result.
If I instead change the type of d to float I get the expected result of 1.0.
I can also change the type of 0.2 to a double which also give the correct
result of 1.0

//Tony

Because computers are binary. Try to express 1/5 as a sum of powers of two.
 
P

Peter Duniho

Tony said:
Hello!

Can somebody explain why I get 1.0000000149011612 when doing this expression
calculation ?
double d = 0.2f + 0.2f + 0.2f + 0.2f + 0.2f;
I know how to fix it that is not the question is about.

See http://en.wikipedia.org/wiki/Floating_point

Also, specifically
http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding

Then, consider whether _either_ float or double can actually represent
exactly the value 0.2. (Hint: neither can).
I now that a double have more then double as many significant number then a
float but can't
still understand the result.
If I instead change the type of d to float I get the expected result of 1.0.

Sure. Because when you lower the precision of the result, the error
that was introduced by the original inexact representation of 0.2 as a
float winds up getting truncated when the magnitude of the floating
point value is increased by a power of 10 at the final addition step,
leaving the exact value of 1.0.

More specifically, the floating point value 0.2f is actually
0.200000003, the closest decimal number to 0.2f that can be represented
in a float. When you add five of those together, you get 1.000000015
numerically, but the closest decimal number to that which can be
represented exactly in a float is actually 1.0000000.

This is a complete coincidence. You can't count on the inexactness
being resolved that way.
I can also change the type of 0.2 to a double which also give the correct
result of 1.0

Same as with float. The error is small enough that after the adding
takes place, it gets lost and you're left (again, coincidentally) with
the exact correct answer.

If you want to represent decimal numbers exactly, you need to use the
System.Decimal type (i.e. "decimal"). Whether you _really_ need to do
that depends on exactly what you're doing with these numbers.

Pete
 
P

Patrice

Hello,

This is just an additional trade off. Basically floating point numbers are
encoded in a way that favor the range (i.e. being able to store both very
small and very high numbers) over the precision. As a result all values
(even some looking very simple to us mere mortals) are not always stored in
an exact way and this approximation sometimes shows up...
 
H

Harlan Messinger

Tony said:
Hello!

Can somebody explain why I get 1.0000000149011612 when doing this expression
calculation ?
double d = 0.2f + 0.2f + 0.2f + 0.2f + 0.2f;
I know how to fix it that is not the question is about.
I now that a double have more then double as many significant number then a
float but can't
still understand the result.
If I instead change the type of d to float I get the expected result of 1.0.
I can also change the type of 0.2 to a double which also give the correct
result of 1.0

Take the representation of 1/3 in decimal form:

0.333333333333...

If you add 1/3 + 1/3 + 1/3 written in decimal form, rounded to 6
significant figures,

0.333333 + 0.333333 + 0.333333

you'll get 0.999999, not 1.

Likewise, the binary representation of the number that, in decimal form,
is 0.2 (or 1/5) is nonterminating:

0.00110011001100110011...

Floats keep 24 significant figures (the first of them, the bit 1, being
implied), so the floating representation of this effectively rounds it to

0.00110011001100110011001101

(the leftmost truncated bit is 1, so it rounds up to a number slightly
larger than 1/5). Multiplying this by 5 gives

1.00000000000000000000000001

or 1 + 1/2^26 = 1.0000000149011612

I think that in C#, float operations are carried out as double
precision. Therefore, when you store the result to a double precision
variable, you see this value. However, since this number has 27
significant figures, when you store it to a float, it gets rounded to 1.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top