Rollup merge of #129559 - RalfJung:float-nan-semantics, r=thomcc · patricklam/verify-rust-std@a628540 (original) (raw)
`@@ -1190,6 +1190,11 @@ mod prim_f16 {}
`
1190
1190
`/// portable or even fully deterministic! This means that there may be some
`
1191
1191
`/// surprising results upon inspecting the bit patterns,
`
1192
1192
`/// as the same calculations might produce NaNs with different bit patterns.
`
``
1193
`` +
/// This also affects the sign of the NaN: checking is_sign_positive
or is_sign_negative
on
``
``
1194
`+
/// a NaN is the most common way to run into these surprising results.
`
``
1195
`` +
/// (Checking x >= 0.0
or x <= 0.0
avoids those surprises, but also how negative/positive
``
``
1196
`+
/// zero are treated.)
`
``
1197
`+
/// See the section below for what exactly is guaranteed about the bit pattern of a NaN.
`
1193
1198
`///
`
1194
1199
`/// When a primitive operation (addition, subtraction, multiplication, or
`
1195
1200
`/// division) is performed on this type, the result is rounded according to the
`
`@@ -1211,6 +1216,79 @@ mod prim_f16 {}
`
1211
1216
`` /// See also the std::f32::consts
module.
``
1212
1217
`///
`
1213
1218
`/// [wikipedia]: https://en.wikipedia.org/wiki/Single-precision_floating-point_format
`
``
1219
`+
///
`
``
1220
`+
/// # NaN bit patterns
`
``
1221
`+
///
`
``
1222
`+
/// This section defines the possible NaN bit patterns returned by non-"bitwise" floating point
`
``
1223
`` +
/// operations. The bitwise operations are unary -
, abs
, copysign
; those are guaranteed to
``
``
1224
`+
/// exactly preserve the bit pattern of their input except for possibly changing the sign bit.
`
``
1225
`+
///
`
``
1226
`+
/// A floating-point NaN value consists of:
`
``
1227
`+
/// - a sign bit
`
``
1228
`+
/// - a quiet/signaling bit
`
``
1229
`+
/// - a payload, which makes up the rest of the significand (i.e., the mantissa) except for the
`
``
1230
`+
/// quiet/signaling bit.
`
``
1231
`+
///
`
``
1232
`` +
/// Rust assumes that the quiet/signaling bit being set to 1
indicates a quiet NaN (QNaN), and a
``
``
1233
`` +
/// value of 0
indicates a signaling NaN (SNaN). In the following we will hence just call it the
``
``
1234
`+
/// "quiet bit".
`
``
1235
`+
///
`
``
1236
`+
/// The following rules apply when a NaN value is returned: the result has a non-deterministic sign.
`
``
1237
`+
/// The quiet bit and payload are non-deterministically chosen from the following set of options:
`
``
1238
`+
///
`
``
1239
`+
/// - Preferred NaN: The quiet bit is set and the payload is all-zero.
`
``
1240
`+
/// - Quieting NaN propagation: The quiet bit is set and the payload is copied from any input
`
``
1241
`+
/// operand that is a NaN. If the inputs and outputs do not have the same payload size (i.e., for
`
``
1242
`` +
/// as
casts), then
``
``
1243
`+
/// - If the output is smaller than the input, low-order bits of the payload get dropped.
`
``
1244
`+
/// - If the output is larger than the input, the payload gets filled up with 0s in the low-order
`
``
1245
`+
/// bits.
`
``
1246
`+
/// - Unchanged NaN propagation: The quiet bit and payload are copied from any input operand
`
``
1247
`` +
/// that is a NaN. If the inputs and outputs do not have the same size (i.e., for as
casts), the
``
``
1248
`+
/// same rules as for "quieting NaN propagation" apply, with one caveat: if the output is smaller
`
``
1249
`+
/// than the input, droppig the low-order bits may result in a payload of 0; a payload of 0 is not
`
``
1250
`+
/// possible with a signaling NaN (the all-0 significand encodes an infinity) so unchanged NaN
`
``
1251
`+
/// propagation cannot occur with some inputs.
`
``
1252
`+
/// - Target-specific NaN: The quiet bit is set and the payload is picked from a target-specific
`
``
1253
`+
/// set of "extra" possible NaN payloads. The set can depend on the input operand values.
`
``
1254
`+
/// See the table below for the concrete NaNs this set contains on various targets.
`
``
1255
`+
///
`
``
1256
`+
/// In particular, if all input NaNs are quiet (or if there are no input NaNs), then the output NaN
`
``
1257
`+
/// is definitely quiet. Signaling NaN outputs can only occur if they are provided as an input
`
``
1258
`+
/// value. Similarly, if all input NaNs are preferred (or if there are no input NaNs) and the target
`
``
1259
`+
/// does not have any "extra" NaN payloads, then the output NaN is guaranteed to be preferred.
`
``
1260
`+
///
`
``
1261
`+
/// The non-deterministic choice happens when the operation is executed; i.e., the result of a
`
``
1262
`+
/// NaN-producing floating point operation is a stable bit pattern (looking at these bits multiple
`
``
1263
`+
/// times will yield consistent results), but running the same operation twice with the same inputs
`
``
1264
`+
/// can produce different results.
`
``
1265
`+
///
`
``
1266
`+
/// These guarantees are neither stronger nor weaker than those of IEEE 754: IEEE 754 guarantees
`
``
1267
`+
/// that an operation never returns a signaling NaN, whereas it is possible for operations like
`
``
1268
`` +
/// SNAN * 1.0
to return a signaling NaN in Rust. Conversely, IEEE 754 makes no statement at all
``
``
1269
`+
/// about which quiet NaN is returned, whereas Rust restricts the set of possible results to the
`
``
1270
`+
/// ones listed above.
`
``
1271
`+
///
`
``
1272
`+
/// Unless noted otherwise, the same rules also apply to NaNs returned by other library functions
`
``
1273
`` +
/// (e.g. min
, minimum
, max
, maximum
); other aspects of their semantics and which IEEE 754
``
``
1274
`+
/// operation they correspond to are documented with the respective functions.
`
``
1275
`+
///
`
``
1276
`` +
/// When a floating-point operation is executed in const
context, the same rules apply: no
``
``
1277
`+
/// guarantee is made about which of the NaN bit patterns described above will be returned. The
`
``
1278
`+
/// result does not have to match what happens when executing the same code at runtime, and the
`
``
1279
`+
/// result can vary depending on factors such as compiler version and flags.
`
``
1280
`+
///
`
``
1281
`+
/// ### Target-specific "extra" NaN values
`
``
1282
`+
// FIXME: Is there a better place to put this?
`
``
1283
`+
///
`
``
1284
`` +
/// | target_arch
| Extra payloads possible on this platform |
``
``
1285
`+
/// |---------------|---------|
`
``
1286
`` +
/// | x86
, x86_64
, arm
, aarch64
, riscv32
, riscv64
| None |
``
``
1287
`` +
/// | sparc
, sparc64
| The all-one payload |
``
``
1288
`` +
/// | wasm32
, wasm64
| If all input NaNs are quiet with all-zero payload: None.
Otherwise: all possible payloads. |
``
``
1289
`+
///
`
``
1290
`+
/// For targets not in this table, all payloads are possible.
`
``
1291
+
1214
1292
`#[stable(feature = "rust1", since = "1.0.0")]
`
1215
1293
`mod prim_f32 {}
`
1216
1294
``