java double calculation

为君一笑 提交于 2019-12-08 00:54:01

问题


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.


回答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



回答2:


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.




回答3:


Rather than try to determine what conditions result in exact or inexact calculations consider using BigDecimal for these situations.




回答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.




回答5:


If comparison is the issue, as a workaround, I would advice to format the numbers in string with 2 decimal places and rounding done and then compare the strings:

        double expectNum = 1849.64;
        double resultNum = 1849.639999;

        String expectedString = String.format("%.2g%n", expectNum);
        String resultString = String.format("%.2g%n", resultNum);

        if(expectedString.equals(resultString)){
           //result matched
           //return true;
        }else{
           //return false;
        }


来源:https://stackoverflow.com/questions/13093982/java-double-calculation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!