java - 为什么 Java 的 double/float Math.min() 是这样实现的?

标签 java floating-point

我正在查看 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数字比整数值复杂得多。
对于这种特定情况,有两个区别很重要:

  • NaNfloat 的有效值和 double它代表“不是数字”并且表现得很奇怪。也就是说,它不等于它自己。
  • 浮点数可以区分 0.0 和 -0.0。当您计算某个函数的极限时,负零可能很有用。区分极限是从正方向还是从负方向接近 0 可能是有益的。

  • 所以这部分:
    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/

    相关文章:

    java - 简单的 Android SUM 和乘法应用程序在 AVD 上崩溃

    c - 混合程序(.asm + .cpp): modify small math program's code to include float input

    java - 更改数据库模式和单元测试

    java - 在 Java 7 中使用 ProcessBuilder 构建流程管道

    java - 使图像遵循帧尺寸

    java - BigDecimal 到 Java/Android 上 BigDecimal 的强大功能

    c++ - 将 float 向上舍入为整数,这有多可靠?

    python - 为什么运行 python 解释器和 python 代码的结果不同?

    Excel将我的数字变成 float

    python - 用于确定两个数字在舍入到 n 个有效十进制数字时是否几乎相等的函数