java double calculation

12,936

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.

Share:
12,936
huahua
Author by

huahua

Updated on August 17, 2022

Comments

  • huahua
    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 and 724.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 is 1849.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
    huahua over 11 years
    thanks sorry forget to mention I do not have access to the code of the old program
  • Yogendra Singh
    Yogendra Singh over 11 years
    @EJP: I mentioned in the beginning itself. Its work around solution for comparison.
  • user207421
    user207421 over 11 years
    He 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
    huahua over 11 years
    I think this line: System.out.println((float) (d + d1)); is narrowing primitive conversion. it convert double to float which narrows the precision.
  • huahua
    huahua over 11 years
    so 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
    huahua over 11 years
    I 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
    huahua over 11 years
    my question is not to fix the program, but find a way to give customer a walk around to pass the validation.
  • Marko Topolnik
    Marko Topolnik over 11 years
    Go 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.