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?
Question posted in Javascript
A very good W3school tutorial can be found here.
A very good W3school tutorial can be found here.
2
Answers
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, wherea
is huge andb
is tiny, then it is possible thatc==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, becausea>0
produces the same answer asa-b>0
.If
a
andb
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.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 toa > 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.00002•2emin from 1.00012•2emin, where emin was the minimum exponent of the format, had to yield zero because 0.00012•2emin 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.