java double 比较相等,比较Java中的相等的double值。

I would like some advice from people who have more experience working with primitive double equality in Java. Using d1 == d2 for two doubles d1 and d2 is not sufficient due to possible rounding errors.

My questions are:

Is Java's Double.compare(d1,d2) == 0 handling rounding errors to some degree? As explained in the 1.7 documentation it returns value 0 if d1 is numerically equal to d2. Is anyone certain what exactly they mean by numerically equal?

Using relative error calculation against some delta value, is there a generic (not application specific) value of delta you would recommend? Please see example below.

Below is a generic function for checking equality considering relative error. What value of delta would you recommend to capture the majority of rounding errors from simple operations +,-,/,* operations?

public static boolean isEqual(double d1, double d2) {

return d1 == d2 || isRelativelyEqual(d1,d2);

}

private static boolean isRelativelyEqual(double d1, double d2) {

return delta > Math.abs(d1- d2) / Math.max(Math.abs(d1), Math.abs(d2));

}

解决方案

You could experiment with delta values in the order of 10-15 but you will notice that some calculations give a larger rounding error. Furthermore, the more operations you make the larger will be the accumulated rounding error.

One particularly bad case is if you subtract two almost equal numbers, for example 1.0000000001 - 1.0 and compare the result to 0.0000000001

So there is little hope to find a generic method that would be applicable in all situations. You always have to calculate the accuracy you can expect in a certain application and then consider results equal if they are closer than this accuracy.

For example the output of

public class Main {

public static double delta(double d1, double d2) {

return Math.abs(d1- d2) / Math.max(Math.abs(d1), Math.abs(d2));

}

public static void main(String[] args) {

System.out.println(delta(0.1*0.1, 0.01));

System.out.println(delta(1.0000000001 - 1.0, 0.0000000001));

}

}

is

1.7347234759768068E-16

8.274036411668976E-8

Interval arithmetic can be used to keep track of the accumulated rounding errors. However in practise the error intervals come out too pessimistic, because sometimes rounding errors also cancel each other.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值