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主要定义一个不平等的订单.更大的数字应该总是更小 - 无论差异有多小.你不想最终得到排序数组:[0.000002, 0.000001, 0.000003].否则,大多数算法(例如二进制搜索)将产生垃圾结果.
如果您希望在限制范围内保持相等,则限制是某些已定义的属性,如线宽,画笔粗细或命中框大小.在这种情况下,您必须比较与该属性的差异而不是硬编码的epsilon.有Float.compare(a,b,epsilon)方法可能有意义.它不是很有用.