英文:
For float numbers a and b, without overflow, underflow and NaN, is a-b>0 always equals to a>b?
问题
例如,如果我想重构代码:a-b>0 到 a>b,它们是否相同?在没有溢出、下溢和 NaN 的情况下,是否存在 a 和 b,使得 a-b>0 和 a>b 的结果不同?例如:a-b 和 a>b 是否使用不同的舍入机制,从而导致不同的结果?
英文:
For example, if I want to refactor the code : a-b>0 to a>b, are they identical? Without overflow, underflow and NaN, is there any a and b that a-b>0 and a>b results in different values? eg: would a-b and a>b use different rounding mechanisms and hence cause different results?
答案1
得分: 4
JavaScript是ECMAScript的实现,ECMAScript规范表示使用IEEE 754算术,采用IEEE-754的“双精度”(binary64)格式。第5.2.5条款指出:“...当应用于数字时,运算符将引用IEEE 754-2019中的相关操作...”
IEEE 754的子规格支持是特定设计的,使得 a-b > 0
等价于 a > b
。一些浮点数系统仅支持规格化的数字,其中主导位必须为1,零的表示除外。在这种系统中,例如,从1.00012•2emin减去1.00002•2emin,其中emin是格式的最小指数,必须产生零,因为0.00012•2emin是不能表示的。在IEEE 754中,这个值是可以表示的,要求减法运算产生它作为结果。
如果这个特性对于应用程序很重要,我会担心一些JavaScript应用程序可能不符合规范。处理器通常有一些模式,在这些模式下会产生零而不是次正常结果,或者将次正常的输入操作数视为零,并且在这种处理器上运行的正确JavaScript实现,如果没有确保禁用该模式,可能会产生不正确的结果。
英文:
JavaScript is an implementation of ECMAScript, and the ECMAScript specification says IEEE 754 arithmetic is used, with the IEEE-754 “double precision” (binary64) format. Clause 5.2.5 says “… When applied to Numbers, the operators refer to the relevant operations within IEEE 754-2019…”
IEEE 754 subnormal support was designed specifically so that a-b > 0
is equivalent to a > b
. Some floating-point systems supported only normalized numbers, in which the leading bit had to be one, except for representations of the number zero. In such systems, subtracting, for example, 1.0000<sub>2</sub>•2<sup>e<sub>min</sub></sup> from 1.0001<sub>2</sub>•2<sup>e<sub>min</sub></sup>, where e<sub>min</sub> was the minimum exponent of the format, had to yield zero because 0.0001<sub>2</sub>•2<sup>e<sub>min</sub></sup> was not representable. In IEEE 754, this value is representable, and the subtraction is required to produce it as the result.
If this property were critical to an application, I would be concerned that some JavaScript application might not conform to the specification. It is not uncommon for processors to have some mode in which they produce zero instead of subnormal results or treat subnormal input operands to arithmetic instructions as zero, and an otherwise correct JavaScript implementation running on such a processor without ensuring that mode is disabled could produce incorrect results.
答案2
得分: 0
很好,你停下来考虑了浮点数的边界情况。答案是是的,这是安全的。
JavaScript中的浮点数存储为64位IEEE 754浮点数。数据结构包括一个符号位,接着是11位指数位,然后是52位尾数(分数)位。
要出现问题,你必须有一种情况,即a-b
减法在极少数情况下产生零而不是微小数字。让我们考虑极端情况:
如果发生 c=a-b
,其中a
是一个巨大的数,而b
是一个微小的数,那么可能 c==a
,因为浮点数没有足够的精度来注意到区别,因为尾数中没有足够的位来表示微小的差异。然而,这不会影响结果,因为 a>0
产生的答案与 a-b>0
相同。
如果 a
和 b
很接近,以至于它们都具有相同的指数位,那么执行减法时不会出现问题,因为尾数将能够捕捉到差异。
英文:
It's good that you've stopped to consider the edge cases with floats. The answer is that yes, this is safe.
Floats in Javascript are stored as 64-bit IEEE 754 floats. The data structure is a sign bit, followed by 11 exponent bits, followed by 52 significand (fractional) bits.
For there to be a problem, you'd have to have a scenario where the a-b
subtraction, in a tiny number of cases, produced zero instead of a tiny number. Let's consider the extremes:
If c=a-b
happens, where a
is huge and b
is tiny, then it is possible that c==a
because the float does not have enough precision to notice the difference, because there are not enough bits available in the significand to represent the tiny difference. However, this will not affect the outcome, because a>0
produces the same answer as a-b>0
.
If a
and b
are very close together, such that they both have the same exponent bits, then there will not be a problem with performing the subtraction, because the significand will be able to capture the difference.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论