当前位置: 首页 > 知识库问答 >
问题:

比较Java中相等的双值。

袁运良
2023-03-14

我想从有更多经验的人那里得到一些建议,他们在Java中使用原始的双相等。由于可能的舍入错误,对两个双d1d2使用d1==d2是不够的。

我的问题是:

>

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

下面是一个通用函数,用于检查考虑相对错误的相等性。您建议delta的值是多少,以捕获简单操作 ,-,/,* 操作中的大部分舍入错误?

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

共有3个答案

穆飞龙
2023-03-14

从javadoc for compareTo

  • 双精度。NaN被此方法认为等于自身并大于所有其他双精度值(包括双精度。POSITIVE_INFINITY)。
  • 此方法认为0.0d大于-0.0d。

你可能会发现这篇文章很有帮助

如果你愿意,你可以像这样检查

double epsilon = 0.0000001;
if      ( d <= ( 0 - epsilon ) ) { .. }
else if ( d >= ( 0 + epsilon ) ) { .. }
else { /* d "equals" zero */ }
封梓
2023-03-14

您可以尝试以下方法(未测试):

public static int sortaClose(double d1, double d2, int bits) {
    long bitMask = 0xFFFFFFFFFFFFFFFFL << bits;
    long thisBits = Double.doubleToLongBits(d1) & bitMask;
    long anotherBits = Double.doubleToLongBits(d2) & bitMask;

    if (thisBits < anotherBits) return -1;
    if (thisBits > anotherBits) return 1;
    return 0;                        
}

“位”通常为1到4左右,这取决于您想要的截止值的精确程度。

一种改进方法是在掩蔽前将第一个要归零的位的位置加1(用于“舍入”),但之后必须担心超过最重要位的波动。

公孙俭
2023-03-14

您可以尝试使用10-15数量级的delta值,但您会注意到某些计算会产生更大的舍入误差。此外,您进行的操作越多,累积的舍入误差就越大。

一种特别糟糕的情况是,如果减去两个几乎相等的数字,例如1.0000000001-1.0,然后将结果与0.0000000001进行比较

因此,几乎没有希望找到一种适用于所有情况的通用方法。您必须始终计算在特定应用程序中可以预期的精度,如果结果接近此精度,则认为结果相等。

例如,输出

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

区间算法可以用来跟踪累积舍入误差。然而在实践中,误差区间过于悲观,因为有时舍入误差也会相互抵消。

 类似资料:
  • 问题内容: 我想从那些在Java中使用原始相等性有更多经验的人那里获得一些建议。使用两次双打,由于可能的舍入误差而不够。 我的问题是: Java 在某种程度上处理舍入错误吗?如1.7文档中所述,如果数值等于,则返回值。有人确定它们在数值上相等是什么意思吗? 对某些增量值使用相对误差计算,您会建议使用通用的增量值(不是特定于应用程序)吗?请参见下面的示例。 以下是考虑相对误差的用于检查相等性的通用函

  • JavaScript 有两种方式判断两个值是否相等。 等于操作符 等于操作符由两个等号组成:== JavaScript 是弱类型语言,这就意味着,等于操作符会为了比较两个值而进行强制类型转换。 "" == "0" // false 0 == "" // true 0 == "0"

  • 问题内容: 我有上述2个类(POJO),它们都是绝对相同的(除了课程名称),我将它们添加到两个数组列表:aListA和aListB。我需要比较两个对象是否相同。如果它们相同,则需要将它们添加到另一个列表(commonList)中,如果它们恰好是不同的,则需要将它们添加到另一个列表(differentList)中。我写了以下代码: 我的问题是,即使两个不同POJO中的数据(变量,firstId和se

  • 问题内容: 是否有用于双重比较的Java库?例如 我开始的每个项目最终都要重新实现,然后粘贴代码并进行测试。 注意,为什么最好使用第三方JAR是IBM的建议一个很好的例子: “如果您不知道基础测量的规模,那么使用测试“ abs(a / b-1)<epsilon”可能比简单比较差异更可靠。” 我怀疑很多人会想到这一点,并说明即使是简单的代码也可能不是最优的。 问题答案: 番石榴有。

  • 问题内容: 首先采取klurudge解决方案,使用哨兵方法(必须让您的程序不允许输入哨兵值): 假设您忘记了阻止程序中的哨兵值,用户在B字段中输入了-2147483648,而A为空。上面的代码报告为true,应报告为false,不应报告为true或null。 比较可为空字段上的相等性的最简洁方法是什么?A == B仅应报告true或false,而不管该字段是否可为空。 问题答案: 也许IS [NO

  • 是否有一种惯用的方法来比较两个NumPy数组,它们将NaN视为彼此相等(但不等于NaN以外的任何东西)。 例如,我希望以下两个数组比较相等: 和以下两个数组进行比较: 我正在寻找一种可以产生标量布尔结果的方法。 以下方法可以做到这一点: 但它很笨重,并且创建了所有这些中间数组。 有没有一种方法可以更容易地观察眼睛,更好地利用记忆? 另外,如果有帮助的话,已知数组具有相同的形状和数据类型。