当前位置: 首页 > 面试题库 >

比较Java中相等性的双精度值。

段干飞翔
2023-03-14
问题内容

我想从那些double在Java中使用原始相等性有更多经验的人那里获得一些建议。使用d1 == d2两次双打d1d2由于可能的舍入误差而不够。

我的问题是:

  1. Java Double.compare(d1,d2) == 0在某种程度上处理舍入错误吗?如1.7文档中所述,0如果d1数值等于,则返回值d2。有人确定它们在数值上相等是什么意思吗?

  2. 对某些增量值使用相对误差计算,您会建议使用通用的增量值(不是特定于应用程序)吗?请参见下面的示例。

以下是考虑相对误差的用于检查相等性的通用函数。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));
}

问题答案:

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

一种特别糟糕的情况是,如果减去两个几乎相等的数字,例如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中使用原始的双相等。由于可能的舍入错误,对两个双和使用是不够的。 我的问题是: > 使用相对误差计算某个增量值,是否有一个通用(而不是特定于应用程序)的增量值值得推荐?请参阅下面的示例。 下面是一个通用函数,用于检查考虑相对错误的相等性。您建议的值是多少,以捕获简单操作 ,-,/,* 操作中的大部分舍入错误?

  • 问题内容: 众所周知,即使是十进制格式的小数点后有固定数字的浮点数也无法准确表示。因此,我有以下程序要测试: 输出如下: 我无法从上述结果中回答两个问题,我正在寻求以下方面的帮助: 为什么使用的双重表示形式,并且看起来很精确,而没有。 为什么返回true? 问题答案: 我怀疑在这里不能正常工作。写入0.1时,获取确切值的一种可靠方法是write 。 “为什么0.1f + 0.2f == 0.3f返

  • 众所周知,浮点数,即使是小数点后固定数字的十进制格式,也不能准确表示。所以我有以下程序要测试: 输出如下: 以上结果中有两个问题我无法回答,我正在寻求帮助: 为什么0.1、0.2和0.3的双重表示看起来很精确,而0.1、0.2却不精确。

  • 问题内容: java中双值的乘法运算符的保证精度是多少? 例如,2.2 * 100是220.00000000000003,但是220是双精度数。220.00000000000003是220之后的下一个两倍。 问题答案: 乘法工作正常,但不能精确表示为双精度。最接近的双打是: 2.199999999999999733(0x4001999999999999) 2.200000000000000177(

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

  • 问题内容: 我正在编写一个简单的Java程序。我需要从输入中获取一个字符串并将其分为两部分:1-double 2-string。然后,我需要对double进行简单的计算,并将结果发送到具有特定精度的输出(4)。它工作正常,但是当输入为0时出现问题,则不能正常工作。 例如,对于这些输入,输出将是: 1公斤 输出:2.2046 3.1公斤 输出:6.8343 但是当输入为0时,输出应为0.0000,但