首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么Java的double/float Math.min()是这样实现的?

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

Stack Overflow用户
提问于 2021-05-06 15:55:15
回答 3查看 5.1K关注 0票数 70

我查看了java.lang.Math源代码中的一些东西,我注意到虽然Math.min(int, int) (或它的长对应项)是这样实现的:

代码语言:javascript
代码运行次数:0
运行
复制
public static int min(int a, int b) {
   return a <= b ? a : b;
}

这对我来说是完全有意义的,这和我会做的是一样的。然而,double/float实现是这样的:

代码语言:javascript
代码运行次数:0
运行
复制
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版本相同的方式实现?

EN

回答 3

Stack Overflow用户

发布于 2021-05-06 16:01:13

Floating-point数比整数值复杂得多。

对于这种特定情况,有两个区别很重要:

  • NaNfloatdouble的有效值,表示“不是数字”,行为怪异。也就是说,它不等于itself.
  • Floating点编号可以区分0.0和-0.0。当你在计算某个函数的极限时,一个负的零值可能会很有用。区分限制是从正方向还是从负方向接近0可能是有益的。

所以这一部分:

代码语言:javascript
代码运行次数:0
运行
复制
if (a != a) {
      return a;
}

确保如果aNaN,则返回NaN (如果a不是NaN,但b是,则稍后的“正常”检查将返回b,即NaN,因此这种情况不需要显式检查)。这是一种常见的模式:在计算输入为NaN的任何内容时,输出也将为NaN

这部分:

代码语言:javascript
代码运行次数:0
运行
复制
if (a == 0.0F && b == 0.0F && (long)Float.floatToRawIntBits(b) == negativeZeroFloatBits) {
      return b;
}

NaN类似,如果正常检查为-0.0且b为0.0,则正常检查将正确返回a

票数 103
EN

Stack Overflow用户

发布于 2021-05-06 16:04:21

我建议仔细阅读Math.min的文档以及关于浮点的numeric comparison operators。他们的行为是完全不同的。

来自Math.min的相关部分

根据IEEE754标准的规范确定的浮点比较结果为:

  • 正零和负零被认为是相等的。

如果任何参数为NaN,Math.min将选取该参数,但如果任何操作数为NaN,则<=的计算结果为false。这就是为什么它必须检查a是否与自身不相等-这意味着a是NaN。

这就是第二次检查的目的。

票数 40
EN

Stack Overflow用户

发布于 2021-05-06 16:14:38

我可以在第一个比较if (a != a)上帮你。这显然只考虑了a,所以在哪些情况下,无论b如何,a都可能是最小的

float数字与int的不同之处在于它有special values,例如NANNAN的一个特殊属性是比较总是假的。因此,如果a上的每个比较运算符都返回false,则第一个条件返回a

在最后一行中可以找到与b相同的条件。如果b上的比较总是返回false,那么最后一行总是返回b

在第二种情况下,我只能猜测这与“负零”和“正零”有关,这是float的另外两个特殊值。当然,负零比正零小。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67414007

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档