为什么他们在Java中使用>,<和==(float float1,float float2)?

Mak*_*iev 2 java floating-point compare

我知道比较浮点数的典型方法,其中解决方案是检查数字是否完全相同,但它们的差异是否非常小:

float a = 0.15 + 0.15;
float b = 0.1 + 0.2;
if( Math.abs(a - b) < 0.00001)
    // The numbers are considered equal
Run Code Online (Sandbox Code Playgroud)

从这里复制了上面的例子.

而现在我不明白为什么以这种方式比较两个浮点变量是正确的:

public static int compare(float float1, float float2) {
    // Non-zero, non-NaN checking.
    if (float1 > float2) {
        return 1;
    }
    if (float2 > float1) {
        return -1;
    }
    if (float1 == float2 && 0.0f != float1) {
        return 0;
    }

    // NaNs are equal to other NaNs and larger than any other float
    if (isNaN(float1)) {
        if (isNaN(float2)) {
            return 0;
        }
        return 1;
    } else if (isNaN(float2)) {
        return -1;
    }

    // Deal with +0.0 and -0.0
    int f1 = floatToRawIntBits(float1);
    int f2 = floatToRawIntBits(float2);
    // The below expression is equivalent to:
    // (f1 == f2) ? 0 : (f1 < f2) ? -1 : 1
    // because f1 and f2 are either 0 or Integer.MIN_VALUE
    return (f1 >> 31) - (f2 >> 31);
}
Run Code Online (Sandbox Code Playgroud)

这是来自Float.compare的源代码(float f1,float f2).

Pio*_*zmo 5

将浮点数与==进行比较不是"不正确".对于不熟悉浮点数的人来说,这可能会产生令人困惑的结果.

在大多数真实的单词场景中,==具有所需的行为.通常,您并不关心数字"几乎"相等.你想要完全平等,因为你正在检查一些角落的情况.

Float.compare主要定义一个不平等的订单.更大的数字应该总是更小 - 无论差异有多小.你不想最终得到排序数组:[0.000002, 0.000001, 0.000003].否则,大多数算法(例如二进制搜索)将产生垃圾结果.

如果您希望在限制范围内保持相等,则限制是某些已定义的属性,如线宽,画笔粗细或命中框大小.在这种情况下,您必须比较与该属性的差异而不是硬编码的epsilon.有Float.compare(a,b,epsilon)方法可能有意义.它不是很有用.