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

``