Apo*_*ara 59 javascript math floating-point min negative-zero
我知道 (-0 === 0) 结果是正确的。我很好奇为什么-0 < 0 会发生?
当我在 stackoverflow 执行上下文中运行此代码时,它返回0.
const arr = [+0, 0, -0];
console.log(Math.min(...arr));Run Code Online (Sandbox Code Playgroud)
但是当我在浏览器控制台中运行相同的代码时,它返回-0. 这是为什么?我尝试在谷歌上搜索它,但没有找到任何有用的东西。这个问题可能不会给某些实际例子增加价值,我想了解 JS 是如何计算它的。
const arr = [+0, 0, -0];
console.log(Math.min(...arr)); // -0
Run Code Online (Sandbox Code Playgroud)
Hol*_*olt 60
-0不小于0or +0,两者-0 < 0都-0 < +0返回False,您将 的行为与/Math.min的比较混合在一起。-00+0
的规范Math.min在这一点上很明确:
\n\nb. 如果数字为 -0 并且最低为 +0,则将最低设置为 -0。
\n
Math.min如果没有这个例外,和的行为Math.max将取决于参数的顺序,这可以被认为是一种奇怪的行为 \xe2\x80\x94 您可能希望Math.min(x, y)始终等于Math.min(y, x)\xe2\x80\x94 因此这可能是一个可能的理由。
注意:此异常已存在于1997 年的规范中,因此Math.min(x, y)不是后来添加的内容。
Jon*_*lms 12
正如所指定的Math.min,这是一个专业:
21.3.2.25 Math.min ( ...args )
[...]
- 对于强制的每个元素数,执行
A。如果数字为 NaN,则返回 NaN。
b. 如果数字为 -0 并且最低为 +0,则将最低设置为 -0。
C。如果数字 < 最低值,则将最低值设置为数字。
- 返回最低。
请注意,在大多数情况下,+0 和 -0 被同等对待,在 ToString 转换中也是如此,因此(-0).toString()计算结果为"0"。您可以在浏览器控制台中观察到的差异是浏览器的实现细节。
这个答案的要点是解释为什么语言设计选择Math.min完全可交换是有意义的。
我很好奇为什么-0 < 0 会发生?
事实并非如此;<是与“最小值”分开的操作,并且Math.min不仅仅基于 IEEE<比较(如b<a ? b : a.
这将是不可交换的。NaN 以及有符号零。(<如果任一操作数为 NaN,则为 false,因此会产生a)。就最小惊奇原则而言,如果是
,那么至少同样令人惊讶(如果不是更令人惊讶的话)。Math.min(-1,NaN)NaNMath.min(NaN, -1)-1
JS 语言设计者想要Math.minNaN 传播,所以仅仅基于它<是不可能的。 他们选择使其完全可交换,包括签名零,这似乎是一个明智的决定。
OTOH,大多数代码并不关心带符号的零,因此这种语言设计选择会牺牲每个人的性能,以满足某些人想要明确定义的带符号零语义的罕见情况。
如果您想要一个忽略数组中 NaN 的简单操作,请使用 进行迭代current_min = x < current_min ? x : current_min。这将忽略所有 NaN,也忽略-0for current_min <= +0.0(IEEE 比较)。或者,如果current_min开始为 NaN,它将保持 NaN。其中许多事情对于Math.min函数来说都是不受欢迎的,所以它不会那样工作。
如果比较其他语言,C 标准fmin函数是可交换的。NaN(如果有则返回非 NaN,与 JS 相反),但不要求是可交换的。签名为零。一些 C 实现选择像 JS 一样工作 +-0.0 for fmin/ fmax。
但C++纯粹std::min 是根据<操作来定义的,所以它确实是这样工作的。(它旨在一般情况下工作,包括字符串等非数字类型;不同之处在于std::fmin它没有任何特定于 FP 的规则。)请参阅在 x86 上提供无分支 FP 最小值和最大值的指令是什么?回复:x86 的minps指令和 C++std::min都是不可交换的。NaN 和有符号零。
IEEE 754<不会为您提供不同 FP 编号的全序。Math.min除了 NaN 之外(例如,如果您用它构建了一个排序网络,并且Math.max。)它的顺序与 不同Math.max:如果存在,它们都返回 NaN,因此使用最小/最大比较器的排序网络将产生所有 NaN(如果存在)输入数组。
Math.min如果没有像查看它返回哪个参数这样的东西,仅靠排序是不够的==,但是对于有符号零和 NaN 来说,这会崩溃。
| 归档时间: |
|
| 查看次数: |
4293 次 |
| 最近记录: |