Skip to content

Commit d307a98

Browse files
committed
Improve some copy in the floats section
There were some long and grammatically involved sentences that it makes sense to refactor a bit here for better readability.
1 parent 4b6db4e commit d307a98

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

posts/2024-10-17-Rust-1.82.0.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,11 +238,11 @@ To avoid interfering with crates that wish to support several Rust versions, `ma
238238

239239
### Floating-point NaN semantics and `const`
240240

241-
Operations on floating-point values (of type `f32` and `f64`) are famously subtle. One of the reasons for this is the existence of "NaN values": this is short for "not a number", and is used to represent e.g. the result of `0.0 / 0.0`. What makes NaN values subtle is that more than one possible NaN value exists: a NaN value has a sign that can be checked with `f.is_sign_positive()`, and it has a "payload" that can be extracted with `f.to_bits()` -- however, both are entirely ignored by `==` (which always returns `false` on a NaN). Despite very successful efforts to standardize the behavior of floating-point operations across hardware architectures, the details of when a NaN is positive or negative and what its exact payload is differ across architectures. To make matters even more complicated, Rust and its LLVM backend apply optimizations to floating-point operations when the exact numeric result is guaranteed not to change, but those optimizations can change which NaN value is produced. For instance, `f * 1.0` may be optimized to just `f`. However, if `f` is a NaN, this can change the exact bit pattern of the result!
241+
Operations on floating-point values (of type `f32` and `f64`) are famously subtle. One of the reasons for this is the existence of NaN ("not a number") values which are used to represent e.g. the result of `0.0 / 0.0`. What makes NaN values subtle is that more than one possible NaN value exists. A NaN value has a sign (that can be checked with `f.is_sign_positive()`) and a payload (that can be extracted with `f.to_bits()`). However, both the sign and payload of NaN values are entirely ignored by `==` (which always returns `false`). Despite very successful efforts to standardize the behavior of floating-point operations across hardware architectures, the details of when a NaN is positive or negative and what its exact payload is differ across architectures. To make matters even more complicated, Rust and its LLVM backend apply optimizations to floating-point operations when the exact numeric result is guaranteed not to change, but those optimizations can change which NaN value is produced. For instance, `f * 1.0` may be optimized to just `f`. However, if `f` is a NaN, this can change the exact bit pattern of the result!
242242

243243
With this release, Rust standardizes on a set of rules for how NaN values behave. This set of rules is *not* fully deterministic, which means that the result of operations like `(0.0 / 0.0).is_sign_positive()` can differ depending on the hardware architecture, optimization levels, and the surrounding code. Code that aims to be fully portable should avoid using `to_bits` and should use `f.signum() == 1.0` instead of `f.is_sign_positive()`. However, the rules are carefully chosen to still allow advanced data representation techniques such as NaN boxing to be implemented in Rust code. For more details on what the exact rules are, check out our [documentation](https://doc.rust-lang.org/std/primitive.f32.html#nan-bit-patterns).
244244

245-
With the semantics for NaN values settled, this release also permits the use of floating-point operations in `const fn`. Due to the reasons described above, operations like `(0.0 / 0.0).is_sign_positive()` can produce a different result when executed at compile-time vs at run-time; this is not a bug and code must not rely on a `const fn` always producing the exact same result.
245+
With the semantics for NaN values settled, this release also permits the use of floating-point operations in `const fn`. Due to the reasons described above, operations like `(0.0 / 0.0).is_sign_positive()` can produce a different result when executed at compile-time vs at run-time. This is not a bug, and code must not rely on a `const fn` always producing the exact same result.
246246

247247
### Constants as assembly immediates
248248

0 commit comments

Comments
 (0)