我知道比较浮点数字的典型方法,解决方法不是检查数字是否完全相同,而是检查它们之间的差异是否很小:
float a = 0.15 + 0.15;
float b = 0.1 + 0.2;
if( Math.abs(a - b) < 0.00001)
// The numbers are considered equal我复制了上面的示例从这里开始。
现在我不明白为什么用这种方式比较两个浮动变量是正确的:
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);
}它来自于Float.compare(浮f1,浮f2)。的源代码
发布于 2015-08-21 09:02:49
将浮标与==进行比较并不“不正确”。对于不熟悉浮点数的人来说,这可能会产生令人困惑的结果。
在大多数真实的单词场景中,==具有所需的行为。通常,您并不关心数字“几乎”相等。你想要完全平等,因为你在检查某个角落的情况。
Float.compare主要定义一个顺序而不是相等。更大的数字应该总是在较小的后面--不管差别有多小。您不想以排序数组结束:[0.000002, 0.000001, 0.000003]。否则,大多数算法(例如二进制搜索)都会产生垃圾结果。
在您希望在限制内相等的情况下,限制是一些已定义的属性,如线宽、刷厚或命中框大小。在这种情况下,您必须将差异与该属性进行比较,而不是硬编码epsilon。使用Float.compare(a,b,epsilon)方法可能是有意义的。只是没什么用。
发布于 2015-08-21 08:21:23
区别在于业务代码和“绝对”代码。
在业务代码中,浮点相等通常以您所描述的方式表示,因此可以将1.000000001和1.000000002视为相等(如果在业务逻辑中有意义的话)。
但是,由于compare方法只是比较两个浮点数,并且不知道1.001和1.002是否应该被认为是相同的,所以它做了一个纯粹的原始计算(以及考虑特殊情况,例如NaN)。
发布于 2015-08-21 08:30:30
Java试图通过检查float1 > float2等来获得一些性能--前3个if块。可以这么说,它可以除掉普通的嫌疑人。假设我想比较10.5f和12.2f,在比较方法开始时进行的if检查会在很早就返回正确的结果,从而获得更好的性能。它不需要到检查的长度,无论是NaN还是比较比特。这是一种低挂水果(哇.“低挂水果”和“通常的嫌疑犯”在一个单一的答案中:)
然后,由于使用java比较的客户端代码可能希望在足够的细节中比较这两个数字,所以java使用按位运算符。
对于正常的比较,几个小数点差是可以接受的。但并不是所有依赖java的应用程序都是如此。
https://stackoverflow.com/questions/32135511
复制相似问题