java double calculation
Solution 1
BigDecimal bigDecimal = new BigDecimal(724.64);
bigDecimal = bigDecimal.add(new BigDecimal(1000.0));
System.out.println(bigDecimal.floatValue());<--Works fine
System.out.println(bigDecimal.doubleValue());<--Works as mentioned in Question
Output:
1724.64
1724.6399999999999
In the first case it works because of narrowing primitive conversion
happens. But with Floating-Point numbers you will have to accept and live with it.
As I stated the reason it is valid for primitives
double d = 724.64;
double d1 = 1000.0;
System.out.println(d + d1);
System.out.println((float) (d + d1));
Output:
1724.64
1724.6399999999999
Solution 2
Rather than try to determine what conditions result in exact or inexact calculations consider using BigDecimal for these situations.
Solution 3
Floating-point numbers don't represent numbers in the decimal, but in binary system and obviously they are of only finite precision, so there is a mismatch between the exact values a decimal system represents and those a floating-point number can represent. You must not expect it to do so.
Solution 4
To answer your final question, a double is exact if the fractional part is a negative power of two, for example zero, 1/2, 1/4, 1/16, ..., It will appear to be exact in some other cases, like the ones you posted, if the API you use to convert them to decimal (for example System.out.println()) does rounding or truncation and the value is close enough that the rounding or truncation yields the expected answer.
huahua
Updated on August 17, 2022Comments
-
huahua almost 2 years
I understand that computer can not represent non-integral numbers precisely. so when I add 2 doubles in java for example:
724.64d + 1000d
the console print out 1724.6399999999999
but why for
724.64d + 100d
and724.64d + 10000d
the console print out 824.64 and 10724.64 separately?
is there a way to know at what condition when I add the 2 doubles, the sum is the exact number ?
The reason why I ask is because that our old program use double to do calculation. and use double comparison to validate the numbers. for example: let us say the total is
1849.64
, all the inputs amounts added up must be equals to total which is1849.64
input 1: 724.64 input 2: 1125
will not work, because the sum will be 1849.6399999999999
but if we input like this below will work, and the sum is 1849.64
input 1: 24.64 input 2: 1825
so how to find those combinations that work? Note, I do not have access to this specific very old program. when the validation failed, we have to manually find a walk around like the second inputs combination. Thanks.
-
huahua over 11 yearsthanks sorry forget to mention I do not have access to the code of the old program
-
Yogendra Singh over 11 years@EJP: I mentioned in the beginning itself. Its work around solution for comparison.
-
user207421 over 11 yearsHe doesn't have control of the source code. He is looking for test data that will work with the existing comparison. Not an answer.
-
huahua over 11 yearsI think this line: System.out.println((float) (d + d1)); is narrowing primitive conversion. it convert double to float which narrows the precision.
-
huahua over 11 yearsso how to locate some other combination quickly to make the sum is 1849.64. such as: input 1: 24.64 input 2: 1825 . or we can only do a random guess?
-
huahua over 11 yearsI know some number can not be represented exactly by binary just like some number can not be represented by decimal exactly such as π . The only choice I have right now is to guess what other combination to pass the validation. I am wondering is there a guild line to do such guess? sometimes we got customer call, they complain about such validation failure stuff, we just need to tell them to try to input this number and that number instead.
-
huahua over 11 yearsmy question is not to fix the program, but find a way to give customer a walk around to pass the validation.
-
Marko Topolnik over 11 yearsGo to this page where they have a Java applet to set each individual bit in a
double
. All numbers that have zeros in the right part of the mantissa will be easier to represent in decimal form. Play around with it a bit to see how it works.