You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: text/0000-float-semantics.md
+5-9Lines changed: 5 additions & 9 deletions
Original file line number
Diff line number
Diff line change
@@ -248,20 +248,16 @@ C23 clarifies its stance on signaling NaNs:
248
248
It doesn't say anything about the bit patterns inside NaNs.
249
249
This means that strictly speaking, any form of NaN boxing has to re-normalize NaNs after every single operation.
250
250
To the author's knowledge, this is not actually done in practice; code instead relies on compilers implementing a more strict semantics.
251
-
The C standard also does not state explicitly whether signaling NaNs can ever be produced by arithmetic operations, though given that the IEEE 754 semantics do not permit this to happen, presumably C does not permit this, either.
252
-
At least [two major C implementations violate this part of the spec](https://godbolt.org/z/6veef68xE) by optimizing `x * 1.0` to `x`.
251
+
However, neither GCC nor MSVC document that they actually provide a more strict semantics.
252
+
253
+
The interpretation of that standard by compilers seems to be that if an operation has a signaling NaN as input, then it may produce a signaling NaN as output.
254
+
(It is not clear to the author how that is a valid interpretation of the above sentence, but the standard itself mentions transforming `x * 1.0` to `x` as a valid transformations
255
+
when the implementation does not have strict support for signaling NaNs.)
253
256
254
257
LLVM [recently adopted](https://github.com/llvm/llvm-project/pull/66579) new NaN rules that this RFC copies exactly into Rust.
255
258
This means that even though arithmetic operations can produce signaling NaNs, there is a guarantee that signaling NaNs will never appear "out of thin air".
256
259
LLVM does not actually document that they are using IEEE float semantics, but de-facto they do on almost all targets (the exception are targets that use x87 instructions, as noted above).
257
260
258
-
GCC [says](https://gcc.gnu.org/wiki/FloatingPointMath) "Without any explicit options, GCC assumes round to nearest or even and does not care about signalling NaNs".
259
-
It is unclear whether "does not care" also means "guarantees to never produce by itself", i.e. whether `0.0 / 0.0` is ever allowed to evaluate to a signaling NaN or not.
260
-
While IEEE 754 forbids such behavior, GCC does [return signaling NaNs from some arithmetic operations](https://godbolt.org/z/6veef68xE), so it is fair to ask under which exact conditions such signaling NaNs may occur.
261
-
If `0.0 / 0.0`*is* allowed to evaluate to a signaling NaN, that is concerning for cases like `pow(1, 0.0/0.0)`, which should return `1` -- but in practice, `pow(1, sNaN)` returns a NaN.
262
-
263
-
MSVCs [documentation of FP behavior](https://learn.microsoft.com/en-us/cpp/build/reference/fp-specify-floating-point-behavior?view=msvc-170) is similarly silent on the issue of whether and when exactly signaling NaNs may be generated, and what the bits of a NaN payload may look like.
264
-
265
261
Java requires exact IEEE 754-2008 compliance and goes through a lot of effort to realize that on 32bit x86 without SSE (see [here](https://open-std.org/jtc1/sc22/jsg/docs/m3/docs/jsgn325.pdf) and [here](https://open-std.org/JTC1/SC22/JSG/docs/m3/docs/jsgn326.pdf)). However, they do not seem to tackle the issue of specifying NaN payload bits, even though those bits [can be observed](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Float.html#floatToRawIntBits(float)).
266
262
267
263
wasm [guarantees](https://webassembly.github.io/spec/core/exec/numerics.html#nan-propagation) that "if all input NaNs are canonical, then any output NaN is canonical". Here ["canonical"](https://webassembly.github.io/spec/core/syntax/values.html#canonical-nan) is defined as a NaN with a "payload whose most significant bit 1 is while all others are 0", i.e. it matches what we call "preferred" above.
0 commit comments