This question is about the IEEE totalOrder
predicate for floats. The algorithm is described in this answer, and also on page 42 of Swartzlander and Lemonds' Computer Arithmetic Volume III:
totalOrder(x, y) imposes a total ordering on canonical members of the format of x and y:
- If x < y, totalOrder(x, y) is true.
- If x > y, totalOrder(x, y) is false.
- If x = y
- totalOrder(−0, +0) is true.
- totalOrder(+0, −0) is false.
- If x and y represent the same floating point datum:
- If x and y have negative sign, totalOrder(x, y) is true if and only if the exponent of x ≥ the exponent of y.
- Otherwise totalOrder(x, y) is true if and only if the exponent of x ≤ the exponent of y.
- If x and y are unordered numerically because x or y is NaN:
- totalOrder(−NaN, y) is true where −NaN represents a NaN with negative sign bit and y is a floating-point number.
- totalOrder(x, +NaN) is true where +NaN represents a NaN with positive sign bit and x is a floating-point number.
- If x and y are both NaNs, then totalOrder reflects a total ordering based on:
- negative sign orders below positive sign
- signaling orders below quiet for +NaN, reverse for −NaN
- lesser payload, when regarded as an integer, orders below greater payload for +NaN, reverse for −NaN.
My question is: What does the bolded part mean? What is an example of two IEEE754 float
bit-patterns where x = y and yet they have different exponents?
Actually the only two IEEE754 floats I can think of that are x = y and have different bit-patterns at all are −0 and +0. NaNs are never equal, and among normal and denormal numbers I'm not aware of any with multiple bit-patterns.
I found a possible (partial) answer at Apple's documentation for isCanonical
:
On platforms that fully support IEEE 754, every Float or Double value is canonical, but non-canonical values can exist on other platforms or for other types. Some examples:
- On platforms that flush subnormal numbers to zero (such as armv7 with the default floating-point environment), Swift interprets subnormal Float and Double values as non-canonical zeros. (In Swift 5.1 and earlier, isCanonical is true for these values, which is the incorrect value.)
- On i386 and x86_64, Float80 has a number of non-canonical encodings. “Pseudo-NaNs”, “pseudo-infinities”, and “unnormals” are interpreted as non-canonical NaN encodings. “Pseudo-denormals” are interpreted as non-canonical encodings of subnormal values.
- Decimal floating-point types admit a large number of non-canonical encodings.
However, if the answer is "Point 3.3 is specifically for the benefit of platforms that do not fully support IEEE754," isn't that kind of weird and circular? And also, taking the first case above (armv7 with all denormals considered =)... since all subnormal/denormal numbers have exactly the same exponent (namely 2−126), point 3.3 doesn't even help to distinguish between them!
So. What's the point/ramifications/intent of this point of the spec?