首页 > 解决方案 > 测试两个双打的近似相等

问题描述

给定这两个 double 值

double d1 = 1.0E-24;
double d2 = 1.0000000000000029E-24;  

和以下功能

public static boolean isEqual(double d0, double d1, double epsilon) {
    return d0 == d1 ? true : Math.abs(d0 - d1) < epsilon;
}

如何计算最小的 epsilon(最小的两倍距离),以便该术语Math.abs(d0 - d1) < epsilon评估为真?

编辑回应评论:

我知道该方法Double.doubleToRawLongBits,但仍需要澄清我需要比较哪些位。所以两个双精度值的二进制表示是

d1: 0 11101011110 0011010101111100001010011001101010001000111010100111

d2: 0 11101011110 0011010101111100001010011001101010001000111010110111

我只需要像这样比较尾数位吗?

isEqual(getMantissaLongBits(d1), getMantissaLongBits(d2), epsilon(getMantissaLongBits(d1), getMantissaLongBits(d2),49))? 

private static long getMantissaLongBits(double x) {
    return Double.doubleToRawLongBits(x) & 0x000fffffffffffffL;
}

public static double epsilon(final double one, final double other, final int bits) {
    return Math.max(Math.scalb(Math.max(Math.abs(one), Math.abs(other)), -bits),
            Math.scalb(Double.MIN_NORMAL, 52 - bits));
}

标签: mathdouble

解决方案


推荐阅读