我正在查看 java.lang.Math
的源代码中的一些内容,我注意到虽然 Math.min(int, int)
(或它的长对应物)是这样实现的:
public static int min(int a, int b) {
return a <= b ? a : b;
}
这对我来说完全有意义,这和我要做的一样。但是,双/浮点实现是这样的:public static float min(float a, float b) {
if (a != a) {
return a;
} else if (a == 0.0F && b == 0.0F && (long)Float.floatToRawIntBits(b) == negativeZeroFloatBits) {
return b;
} else {
return a <= b ? a : b;
}
}
我完全傻眼了。比较 a
对自己?第二次检查是为了什么?为什么它的实现方式与 int/long 版本不同?
最佳答案
Floating-point数字比整数值复杂得多。
对于这种特定情况,有两个区别很重要:
NaN
是 float
的有效值和 double
它代表“不是数字”并且表现得很奇怪。也就是说,它不等于它自己。 所以这部分:
if (a != a) {
return a;
}
确保 NaN
如果 a
则返回是 NaN
(如果 a
不是 NaN
,而是 b
,则稍后的“正常”检查将返回 b
,即 NaN
,因此这种情况不需要显式检查)。这是一种常见的模式:当计算任何输入为 NaN
时,输出也将是 NaN
.自 NaN
通常代表计算中的一些错误(例如 0 除以 0),重要的是它“毒化”所有进一步的计算以确保错误不会被默默吞下。这部分:
if (a == 0.0F && b == 0.0F && (long)Float.floatToRawIntBits(b) == negativeZeroFloatBits) {
return b;
}
确保如果您比较两个零值浮点数和 b
是负零,则返回负零(因为 -0.0 “小于”0.0)。类似于 NaN
正常检查将正确返回 a
如果它是 -0.0 和 b
是 0.0。
关于java - 为什么 Java 的 double/float Math.min() 是这样实现的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67414007/