Sum of decimal number in java

拟墨画扇 提交于 2019-11-28 13:51:19

You can get rounding error, but I don't see it here.

final double first=198.4;//value extract by unmodifiable format method
final double second=44701.2;//value extract by unmodifiable format method
final double firstDifference= first+second; //I receive 44899.6
final double calculatedDifference=44900.1; // comparison value for the flow
final double error=firstDifference-calculatedDifference;// I receive -0.5 

if(Math.abs(error)<=0.5d){
    // this branch is entered.
    System.out.println(error);
}

prints

-0.5

There are two ways to handle this more generally. You can define a rounding error such as

 private static final double ERROR = 1e-9;

 if(Math.abs(error)<=0.5d + ERROR){

OR use rounding

final double firstDifference= round(first+second, 1); // call a function to round to one decimal place.

OR use integers with fixed precision

final int first=1984;// 198.4 * 10
final int second=447012; // 44701.2 * 10
final int firstDifference= first+second;  //I receive 448996
final int calculatedDifference=449001; // comparison value for the flow
final int error=firstDifference-calculatedDifference;// I receive -5 

if(Math.abs(error)<=5){
    // this branch is entered.
    System.out.println(error);
}

OR You can use BigDecimal. This is often the preferred solution for many developers, but a last option IMHO. ;)

This error will depend slightly on your version of Java (and I see you are using a slightly old one). However, regardless of Java version, for best results when you are particularly worried about decimal accuracy in java, you should use the BigDecimal class for your values.

This is what financial applications use for handling currency, and also what many industrial Java applications use when precision is essential.

EDIT: I see many valid comments that this solution comes with a slight performance hit (also depends on the number of operations you are doing in the first place). And really, if this is the only single place that you encounter an issue and you dont care about precision after it, then ya, go for a workaround. But if this happens frequently and in more than one place, or if you think you might be expanding your application in the future, I would use the safer BigDecimal.

Kurru

Double items store number in powers of 2. It is not possible to accurately represent a lot of numbers in terms of powers of 2 and so you get rounding issues. The same problem when using floats.

If you want to reduce these, use the Decimal type for the numbers, this should prove to be more accurate.

For doubles and floats, you must use the < comparator to check if 2 numbers are close enough to be considered equal.

See this for more details -> What is the most effective way for float and double comparison?

I've tested and on my machine everything is correct (tested in java 1.6). If I were you I would test strictfp modifier to method which has above operations:

public static strictfp void main(String[] args)

The problem can be connected with java version, OS, CPU you're using

I agree with Peter, I don't see that happening either. However, if it keeps happening to you and if the number of decimals is known and fixed in your usecase anyway, using "int" might be a solution, that's even faster than floating point operations. For the views you would then have to convert to floating points, of course.

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