Mat Austin

Greenhorn

Posts: 7

posted 11 years ago

Hi,

I am trying to uderstand the maths behind doubles (and floats). It seems that if you divide 1.0 by 3, assign a double reference to this number and then multiply the result by 3, then you get 1.0 again.

Obviously this is what you want and the answer is correct. However, I would be grateful if someonoe could explain how java processes this. Since the double is only finitely long, it would need to be rounded at some point. Therefore, how does the JVM know that the instance variable is actually 1 / 3 and not 0.3333333...

Thanks in advance,

Matt

I am trying to uderstand the maths behind doubles (and floats). It seems that if you divide 1.0 by 3, assign a double reference to this number and then multiply the result by 3, then you get 1.0 again.

Obviously this is what you want and the answer is correct. However, I would be grateful if someonoe could explain how java processes this. Since the double is only finitely long, it would need to be rounded at some point. Therefore, how does the JVM know that the instance variable is actually 1 / 3 and not 0.3333333...

Thanks in advance,

Matt

Peter Chase

Ranch Hand

Posts: 1970

posted 11 years ago

It doesn't. You just happen to have got lucky that the rounding errors cancel out in this case.

When using floating-point arithmetic, you can never trust the last digit. Certain types of calculation, particularly subtracting very similar numbers, increase rounding errors so they can creep into more digits. With very complex calculations, it can go completely wrong.

This is not a feature of Java, it's a feature of floating-point. There are many occasions when floating-point is a good choice, but there are many when it isn't. The most common situation where floating point should be avoided is calculations involving currency. Those should be done in integer arithmetic, which is exact, whenever possible.

When using floating-point arithmetic, you can never trust the last digit. Certain types of calculation, particularly subtracting very similar numbers, increase rounding errors so they can creep into more digits. With very complex calculations, it can go completely wrong.

This is not a feature of Java, it's a feature of floating-point. There are many occasions when floating-point is a good choice, but there are many when it isn't. The most common situation where floating point should be avoided is calculations involving currency. Those should be done in integer arithmetic, which is exact, whenever possible.

Betty Rubble? Well, I would go with Betty... but I'd be thinking of Wilma.

Mat Austin

Greenhorn

Posts: 7

posted 11 years ago

Cool. Thanks for your help.

There is one thing that I'm still not quite clear on, though. In the following code...

double x = 1.0 / 3.0;

double y = x * 3.0;

System.out.println( y ) ;

The return value is 1.0. When x is inititalised it has to be rounded at some point. Therefore is is either 0.3333.....3 or 0.3333...4. So when you multiple x by 3 you should either get 0.9999...9 or 1.0000...2.

You said that it is chance that the rounding errors cancel out in this case but I'm not entirely clear how this can work? I would be really grateful for any further feedback.

Thanks

Matt

There is one thing that I'm still not quite clear on, though. In the following code...

double x = 1.0 / 3.0;

double y = x * 3.0;

System.out.println( y ) ;

The return value is 1.0. When x is inititalised it has to be rounded at some point. Therefore is is either 0.3333.....3 or 0.3333...4. So when you multiple x by 3 you should either get 0.9999...9 or 1.0000...2.

You said that it is chance that the rounding errors cancel out in this case but I'm not entirely clear how this can work? I would be really grateful for any further feedback.

Thanks

Matt

posted 11 years ago

Floating point numbers in a float or double are stored using the IEEE 754 floating point standard. Ofcourse the precision is limited, because only a limited number of bits is available (32 bits for a float, 64 bits for a double).

Note that floating point numbers are stored using bits - binary digits - like every piece of information in a computer. So a number like 0.33333.... isn't rounded to 0.3333...3 somewhere (that's just the decimal representation). The Wikipedia example I provided a link to above explains in detail how the bits are laid out in a float or double.

If you want to know the exact details, then you can work out what the bit pattern is of the variables x and y and what happens exactly.

Note that floating point numbers are stored using bits - binary digits - like every piece of information in a computer. So a number like 0.33333.... isn't rounded to 0.3333...3 somewhere (that's just the decimal representation). The Wikipedia example I provided a link to above explains in detail how the bits are laid out in a float or double.

If you want to know the exact details, then you can work out what the bit pattern is of the variables x and y and what happens exactly.