PDA

View Full Version : java doesn't know how to substract



newen
August 21st, 2006, 08:44 AM
Try this and tell me what u get.


double result= 1.03-.42;
double wrongResult = .61-result;
if (wrongResult != 0.0)
System.out.println(wrongResult);

Is this a java precision bug?

Cryonic
August 21st, 2006, 09:24 AM
It's not, it's a feature ;)
If you read the docs at Sun

http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html

it says:


double: The double data type is a double-precision 64-bit IEEE 754 floating point. Its range of values is beyond the scope of this discussion, but is specified in section 4.2.3 of the Java Language Specification. For decimal values, this data type is generally the default choice. As mentioned above, this data type should never be used for precise values, such as currency.

for your example, use the float type instead:



float result= 1.03f-.42f;
float wrongResult = .61f-result;
if (wrongResult != 0.0)
System.out.println(wrongResult);

LordHunter317
August 21st, 2006, 01:47 PM
Umm, float is also a IEEE-754 floating point value, just of less precision.

Read: http://docs.sun.com/source/806-3568/ncg_goldberg.html and note it's probably one of the only pieces of really good documentation Sun has ever written.

newen
August 21st, 2006, 02:30 PM
BigDecimal does neither give correct results. Try it, it's even worse than double!.

LordHunter317
August 21st, 2006, 03:49 PM
If you used it the way I think you did, then of course it doesn't give correct results, because it can't.

Did you read the document above? Until you do, please do not post anymore on this subject.

Don't post about BigDecimal either until you read it's documentation carefully. Especially if you're using the Java 5 version, which provides a lot of complicated rounding and precision support.

yaaarrrgg
August 21st, 2006, 03:59 PM
I think you should generally avoid equality comparisons on floats and doubles in any langauge. consider this:



clearly:
1/3 + 1/3 + 1/3 = 1
and
.333... + .333... + .333... = .999...
note:
1/3 == .333...
therefore:
.999... == 1


This has nothing to do with precision erros. The result is actually true.

LordHunter317
August 21st, 2006, 04:08 PM
I think you should generally avoid equality comparisons on floats and doubles in any langauge.Yes, but not for the reason you state. 1/3 is not equal to .333. It's about equal to .333. It is equal to .3 infinitely repeating.

That difference is subtle, but fundamentally important, especially when dealing with fixed-precision systems.

This is why we deal with rationals in a special way if we need arbitrary percision, normally.

LordHunter317
August 21st, 2006, 04:55 PM
I see now I think you're saying the same thing as I was. Was the '...' meant to mean infinitely repeating?

Anyway, like I said, if this is a problem, you deal with rationals specially. Otherwise, you accept the small error and get on with life.

But that's still not a good reason to not do equality on IEEE-754 floating-point values. The fact they can't represent every value is reason enough. Anything else is a strawman ultimately.

Cryonic
August 21st, 2006, 06:18 PM
Umm, float is also a IEEE-754 floating point value, just of less precision.

Read: http://docs.sun.com/source/806-3568/ncg_goldberg.html and note it's probably one of the only pieces of really good documentation Sun has ever written.

You're totally right, I was reading carelessly.
And thanks for the link, it's a good read! :)

yaaarrrgg
August 21st, 2006, 07:37 PM
I see now I think you're saying the same thing as I was. Was the '...' meant to mean infinitely repeating?

Yes... my fault for not being clear.

I thought the OP was assuming that more precision would fix the problem.

But even with infinite precision, there's still difficulties with strict equality comparisons on real numbers. At bottom, I think a '=' relation between two reals must be interpreted as a more verbose relation involving '<', '>' and arbitrarily small errors. I'm not sure the idea of strict equality between two reals even makes logical sense (unless they can be pre-converted into fractions).