比较Java中的相等的double值。 [英] Comparing double values for equality in Java.

查看:2569
本文介绍了比较Java中的相等的double值。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一些有更多经验的人的建议,他们使用Java中的原始 double 相等。使用 d1 == d2 进行两次双打 d1 d2 是不够的,因为可能的舍入误差。

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.

我的问题是:


  1. Java的 Double.compare(d1,d2)== 0 在一定程度上处理舍入错误?如 1.7文档如果 d1 在数值上等于 d2 返回值 0 >。有没有人确定他们在数字上相等的含义是什么?

  1. 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?

对某个delta值使用相对误差计算,是否有一个通用(不是特定于应用程序的)delta你会推荐吗?请参阅下面的示例。

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));
}


推荐答案

您可以尝试增量值按照10 -15 的顺序,但是您会注意到一些计算给出了更大的舍入误差。此外,您所做的更大的操作将是累积的舍入误差。

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.

一个特别糟糕的情况是如果减去两个几乎相等的数字,例如1.0000000001 - 1.0和将结果与0.0000000001

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.

例如

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));
    }

}

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.

这篇关于比较Java中的相等的double值。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆