]> git.proxmox.com Git - rustc.git/blame - library/core/src/num/f32.rs
bump version to 1.79.0+dfsg1-1~bpo12+pve2
[rustc.git] / library / core / src / num / f32.rs
CommitLineData
f2b60f7d 1//! Constants for the `f32` single-precision floating point type.
ff7c6d11 2//!
6a06907d 3//! *[See also the `f32` primitive type][f32].*
94b46f34
XL
4//!
5//! Mathematically significant numbers are provided in the `consts` sub-module.
74b04a01 6//!
5869c6ff
XL
7//! For the constants defined directly in this module
8//! (as distinct from those defined in the `consts` sub-module),
9//! new code should instead use the associated constants
10//! defined directly on the `f32` type.
1a4d82fc 11
85aaf69f 12#![stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 13
60c5eb7d 14use crate::convert::FloatToInt;
dc9dc135
XL
15#[cfg(not(test))]
16use crate::intrinsics;
48663c56
XL
17use crate::mem;
18use crate::num::FpCategory;
1a4d82fc 19
5bcae85e 20/// The radix or base of the internal representation of `f32`.
6a06907d 21/// Use [`f32::RADIX`] instead.
f9f354fc
XL
22///
23/// # Examples
24///
25/// ```rust
26/// // deprecated way
5869c6ff 27/// # #[allow(deprecated, deprecated_in_future)]
f9f354fc
XL
28/// let r = std::f32::RADIX;
29///
30/// // intended way
31/// let r = f32::RADIX;
32/// ```
c34b1796 33#[stable(feature = "rust1", since = "1.0.0")]
04454e1e 34#[deprecated(since = "TBD", note = "replaced by the `RADIX` associated constant on `f32`")]
c620b35d 35#[rustc_diagnostic_item = "f32_legacy_const_radix"]
74b04a01 36pub const RADIX: u32 = f32::RADIX;
1a4d82fc 37
5bcae85e 38/// Number of significant digits in base 2.
6a06907d 39/// Use [`f32::MANTISSA_DIGITS`] instead.
f9f354fc
XL
40///
41/// # Examples
42///
43/// ```rust
44/// // deprecated way
5869c6ff 45/// # #[allow(deprecated, deprecated_in_future)]
f9f354fc
XL
46/// let d = std::f32::MANTISSA_DIGITS;
47///
48/// // intended way
49/// let d = f32::MANTISSA_DIGITS;
50/// ```
c34b1796 51#[stable(feature = "rust1", since = "1.0.0")]
04454e1e 52#[deprecated(
5869c6ff 53 since = "TBD",
04454e1e 54 note = "replaced by the `MANTISSA_DIGITS` associated constant on `f32`"
5869c6ff 55)]
c620b35d 56#[rustc_diagnostic_item = "f32_legacy_const_mantissa_dig"]
74b04a01 57pub const MANTISSA_DIGITS: u32 = f32::MANTISSA_DIGITS;
f9f354fc 58
5bcae85e 59/// Approximate number of significant digits in base 10.
6a06907d 60/// Use [`f32::DIGITS`] instead.
f9f354fc
XL
61///
62/// # Examples
63///
64/// ```rust
65/// // deprecated way
5869c6ff 66/// # #[allow(deprecated, deprecated_in_future)]
f9f354fc
XL
67/// let d = std::f32::DIGITS;
68///
69/// // intended way
70/// let d = f32::DIGITS;
71/// ```
c34b1796 72#[stable(feature = "rust1", since = "1.0.0")]
04454e1e 73#[deprecated(since = "TBD", note = "replaced by the `DIGITS` associated constant on `f32`")]
c620b35d 74#[rustc_diagnostic_item = "f32_legacy_const_digits"]
74b04a01 75pub const DIGITS: u32 = f32::DIGITS;
1a4d82fc 76
94b46f34 77/// [Machine epsilon] value for `f32`.
6a06907d 78/// Use [`f32::EPSILON`] instead.
94b46f34 79///
60c5eb7d 80/// This is the difference between `1.0` and the next larger representable number.
94b46f34
XL
81///
82/// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon
f9f354fc
XL
83///
84/// # Examples
85///
86/// ```rust
87/// // deprecated way
5869c6ff 88/// # #[allow(deprecated, deprecated_in_future)]
f9f354fc
XL
89/// let e = std::f32::EPSILON;
90///
91/// // intended way
92/// let e = f32::EPSILON;
93/// ```
85aaf69f 94#[stable(feature = "rust1", since = "1.0.0")]
04454e1e 95#[deprecated(since = "TBD", note = "replaced by the `EPSILON` associated constant on `f32`")]
c620b35d 96#[rustc_diagnostic_item = "f32_legacy_const_epsilon"]
74b04a01 97pub const EPSILON: f32 = f32::EPSILON;
1a4d82fc 98
5bcae85e 99/// Smallest finite `f32` value.
6a06907d 100/// Use [`f32::MIN`] instead.
f9f354fc
XL
101///
102/// # Examples
103///
104/// ```rust
105/// // deprecated way
5869c6ff 106/// # #[allow(deprecated, deprecated_in_future)]
f9f354fc
XL
107/// let min = std::f32::MIN;
108///
109/// // intended way
110/// let min = f32::MIN;
111/// ```
85aaf69f 112#[stable(feature = "rust1", since = "1.0.0")]
04454e1e 113#[deprecated(since = "TBD", note = "replaced by the `MIN` associated constant on `f32`")]
c620b35d 114#[rustc_diagnostic_item = "f32_legacy_const_min"]
74b04a01 115pub const MIN: f32 = f32::MIN;
f9f354fc 116
5bcae85e 117/// Smallest positive normal `f32` value.
6a06907d 118/// Use [`f32::MIN_POSITIVE`] instead.
f9f354fc
XL
119///
120/// # Examples
121///
122/// ```rust
123/// // deprecated way
5869c6ff 124/// # #[allow(deprecated, deprecated_in_future)]
f9f354fc
XL
125/// let min = std::f32::MIN_POSITIVE;
126///
127/// // intended way
128/// let min = f32::MIN_POSITIVE;
129/// ```
85aaf69f 130#[stable(feature = "rust1", since = "1.0.0")]
04454e1e 131#[deprecated(since = "TBD", note = "replaced by the `MIN_POSITIVE` associated constant on `f32`")]
c620b35d 132#[rustc_diagnostic_item = "f32_legacy_const_min_positive"]
74b04a01 133pub const MIN_POSITIVE: f32 = f32::MIN_POSITIVE;
f9f354fc 134
5bcae85e 135/// Largest finite `f32` value.
6a06907d 136/// Use [`f32::MAX`] instead.
f9f354fc
XL
137///
138/// # Examples
139///
140/// ```rust
141/// // deprecated way
5869c6ff 142/// # #[allow(deprecated, deprecated_in_future)]
f9f354fc
XL
143/// let max = std::f32::MAX;
144///
145/// // intended way
146/// let max = f32::MAX;
147/// ```
85aaf69f 148#[stable(feature = "rust1", since = "1.0.0")]
04454e1e 149#[deprecated(since = "TBD", note = "replaced by the `MAX` associated constant on `f32`")]
c620b35d 150#[rustc_diagnostic_item = "f32_legacy_const_max"]
74b04a01 151pub const MAX: f32 = f32::MAX;
85aaf69f 152
5bcae85e 153/// One greater than the minimum possible normal power of 2 exponent.
6a06907d 154/// Use [`f32::MIN_EXP`] instead.
f9f354fc
XL
155///
156/// # Examples
157///
158/// ```rust
159/// // deprecated way
5869c6ff 160/// # #[allow(deprecated, deprecated_in_future)]
f9f354fc
XL
161/// let min = std::f32::MIN_EXP;
162///
163/// // intended way
164/// let min = f32::MIN_EXP;
165/// ```
c34b1796 166#[stable(feature = "rust1", since = "1.0.0")]
04454e1e 167#[deprecated(since = "TBD", note = "replaced by the `MIN_EXP` associated constant on `f32`")]
c620b35d 168#[rustc_diagnostic_item = "f32_legacy_const_min_exp"]
74b04a01 169pub const MIN_EXP: i32 = f32::MIN_EXP;
f9f354fc 170
5bcae85e 171/// Maximum possible power of 2 exponent.
6a06907d 172/// Use [`f32::MAX_EXP`] instead.
f9f354fc
XL
173///
174/// # Examples
175///
176/// ```rust
177/// // deprecated way
5869c6ff 178/// # #[allow(deprecated, deprecated_in_future)]
f9f354fc
XL
179/// let max = std::f32::MAX_EXP;
180///
181/// // intended way
182/// let max = f32::MAX_EXP;
183/// ```
c34b1796 184#[stable(feature = "rust1", since = "1.0.0")]
04454e1e 185#[deprecated(since = "TBD", note = "replaced by the `MAX_EXP` associated constant on `f32`")]
c620b35d 186#[rustc_diagnostic_item = "f32_legacy_const_max_exp"]
74b04a01 187pub const MAX_EXP: i32 = f32::MAX_EXP;
1a4d82fc 188
5bcae85e 189/// Minimum possible normal power of 10 exponent.
6a06907d 190/// Use [`f32::MIN_10_EXP`] instead.
f9f354fc
XL
191///
192/// # Examples
193///
194/// ```rust
195/// // deprecated way
5869c6ff 196/// # #[allow(deprecated, deprecated_in_future)]
f9f354fc
XL
197/// let min = std::f32::MIN_10_EXP;
198///
199/// // intended way
200/// let min = f32::MIN_10_EXP;
201/// ```
c34b1796 202#[stable(feature = "rust1", since = "1.0.0")]
04454e1e 203#[deprecated(since = "TBD", note = "replaced by the `MIN_10_EXP` associated constant on `f32`")]
c620b35d 204#[rustc_diagnostic_item = "f32_legacy_const_min_10_exp"]
74b04a01 205pub const MIN_10_EXP: i32 = f32::MIN_10_EXP;
f9f354fc 206
5bcae85e 207/// Maximum possible power of 10 exponent.
6a06907d 208/// Use [`f32::MAX_10_EXP`] instead.
f9f354fc
XL
209///
210/// # Examples
211///
212/// ```rust
213/// // deprecated way
5869c6ff 214/// # #[allow(deprecated, deprecated_in_future)]
f9f354fc
XL
215/// let max = std::f32::MAX_10_EXP;
216///
217/// // intended way
218/// let max = f32::MAX_10_EXP;
219/// ```
c34b1796 220#[stable(feature = "rust1", since = "1.0.0")]
04454e1e 221#[deprecated(since = "TBD", note = "replaced by the `MAX_10_EXP` associated constant on `f32`")]
c620b35d 222#[rustc_diagnostic_item = "f32_legacy_const_max_10_exp"]
74b04a01 223pub const MAX_10_EXP: i32 = f32::MAX_10_EXP;
1a4d82fc 224
5bcae85e 225/// Not a Number (NaN).
6a06907d 226/// Use [`f32::NAN`] instead.
f9f354fc
XL
227///
228/// # Examples
229///
230/// ```rust
231/// // deprecated way
5869c6ff 232/// # #[allow(deprecated, deprecated_in_future)]
f9f354fc
XL
233/// let nan = std::f32::NAN;
234///
235/// // intended way
236/// let nan = f32::NAN;
237/// ```
85aaf69f 238#[stable(feature = "rust1", since = "1.0.0")]
04454e1e 239#[deprecated(since = "TBD", note = "replaced by the `NAN` associated constant on `f32`")]
c620b35d 240#[rustc_diagnostic_item = "f32_legacy_const_nan"]
74b04a01 241pub const NAN: f32 = f32::NAN;
f9f354fc 242
5bcae85e 243/// Infinity (∞).
6a06907d 244/// Use [`f32::INFINITY`] instead.
f9f354fc
XL
245///
246/// # Examples
247///
248/// ```rust
249/// // deprecated way
5869c6ff 250/// # #[allow(deprecated, deprecated_in_future)]
f9f354fc
XL
251/// let inf = std::f32::INFINITY;
252///
253/// // intended way
254/// let inf = f32::INFINITY;
255/// ```
85aaf69f 256#[stable(feature = "rust1", since = "1.0.0")]
04454e1e 257#[deprecated(since = "TBD", note = "replaced by the `INFINITY` associated constant on `f32`")]
c620b35d 258#[rustc_diagnostic_item = "f32_legacy_const_infinity"]
74b04a01 259pub const INFINITY: f32 = f32::INFINITY;
f9f354fc 260
dfeec247 261/// Negative infinity (−∞).
6a06907d 262/// Use [`f32::NEG_INFINITY`] instead.
f9f354fc
XL
263///
264/// # Examples
265///
266/// ```rust
267/// // deprecated way
5869c6ff 268/// # #[allow(deprecated, deprecated_in_future)]
f9f354fc
XL
269/// let ninf = std::f32::NEG_INFINITY;
270///
271/// // intended way
272/// let ninf = f32::NEG_INFINITY;
273/// ```
85aaf69f 274#[stable(feature = "rust1", since = "1.0.0")]
04454e1e 275#[deprecated(since = "TBD", note = "replaced by the `NEG_INFINITY` associated constant on `f32`")]
c620b35d 276#[rustc_diagnostic_item = "f32_legacy_const_neg_infinity"]
74b04a01 277pub const NEG_INFINITY: f32 = f32::NEG_INFINITY;
1a4d82fc 278
b039eaaf 279/// Basic mathematical constants.
c34b1796 280#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
281pub mod consts {
282 // FIXME: replace with mathematical constants from cmath.
283
5bcae85e 284 /// Archimedes' constant (π)
c34b1796 285 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
286 pub const PI: f32 = 3.14159265358979323846264338327950288_f32;
287
60c5eb7d
XL
288 /// The full circle constant (τ)
289 ///
290 /// Equal to 2π.
3dfed10e 291 #[stable(feature = "tau_constant", since = "1.47.0")]
60c5eb7d
XL
292 pub const TAU: f32 = 6.28318530717958647692528676655900577_f32;
293
781aab86
FG
294 /// The golden ratio (φ)
295 #[unstable(feature = "more_float_constants", issue = "103883")]
296 pub const PHI: f32 = 1.618033988749894848204586834365638118_f32;
297
298 /// The Euler-Mascheroni constant (γ)
299 #[unstable(feature = "more_float_constants", issue = "103883")]
300 pub const EGAMMA: f32 = 0.577215664901532860606512090082402431_f32;
301
5bcae85e 302 /// π/2
c34b1796 303 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
304 pub const FRAC_PI_2: f32 = 1.57079632679489661923132169163975144_f32;
305
5bcae85e 306 /// π/3
c34b1796 307 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
308 pub const FRAC_PI_3: f32 = 1.04719755119659774615421446109316763_f32;
309
5bcae85e 310 /// π/4
c34b1796 311 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
312 pub const FRAC_PI_4: f32 = 0.785398163397448309615660845819875721_f32;
313
5bcae85e 314 /// π/6
c34b1796 315 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
316 pub const FRAC_PI_6: f32 = 0.52359877559829887307710723054658381_f32;
317
5bcae85e 318 /// π/8
c34b1796 319 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
320 pub const FRAC_PI_8: f32 = 0.39269908169872415480783042290993786_f32;
321
5bcae85e 322 /// 1/π
c34b1796 323 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
324 pub const FRAC_1_PI: f32 = 0.318309886183790671537767526745028724_f32;
325
781aab86
FG
326 /// 1/sqrt(π)
327 #[unstable(feature = "more_float_constants", issue = "103883")]
328 pub const FRAC_1_SQRT_PI: f32 = 0.564189583547756286948079451560772586_f32;
329
5bcae85e 330 /// 2/π
c34b1796 331 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
332 pub const FRAC_2_PI: f32 = 0.636619772367581343075535053490057448_f32;
333
5bcae85e 334 /// 2/sqrt(π)
c34b1796
AL
335 #[stable(feature = "rust1", since = "1.0.0")]
336 pub const FRAC_2_SQRT_PI: f32 = 1.12837916709551257389615890312154517_f32;
337
5bcae85e 338 /// sqrt(2)
c34b1796
AL
339 #[stable(feature = "rust1", since = "1.0.0")]
340 pub const SQRT_2: f32 = 1.41421356237309504880168872420969808_f32;
341
5bcae85e 342 /// 1/sqrt(2)
c34b1796
AL
343 #[stable(feature = "rust1", since = "1.0.0")]
344 pub const FRAC_1_SQRT_2: f32 = 0.707106781186547524400844362104849039_f32;
345
781aab86
FG
346 /// sqrt(3)
347 #[unstable(feature = "more_float_constants", issue = "103883")]
348 pub const SQRT_3: f32 = 1.732050807568877293527446341505872367_f32;
349
350 /// 1/sqrt(3)
351 #[unstable(feature = "more_float_constants", issue = "103883")]
352 pub const FRAC_1_SQRT_3: f32 = 0.577350269189625764509148780501957456_f32;
353
5bcae85e 354 /// Euler's number (e)
c34b1796 355 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
356 pub const E: f32 = 2.71828182845904523536028747135266250_f32;
357
5bcae85e 358 /// log<sub>2</sub>(e)
c34b1796 359 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
360 pub const LOG2_E: f32 = 1.44269504088896340735992468100189214_f32;
361
94b46f34 362 /// log<sub>2</sub>(10)
74b04a01 363 #[stable(feature = "extra_log_consts", since = "1.43.0")]
94b46f34
XL
364 pub const LOG2_10: f32 = 3.32192809488736234787031942948939018_f32;
365
5bcae85e 366 /// log<sub>10</sub>(e)
c34b1796 367 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
368 pub const LOG10_E: f32 = 0.434294481903251827651128918916605082_f32;
369
94b46f34 370 /// log<sub>10</sub>(2)
74b04a01 371 #[stable(feature = "extra_log_consts", since = "1.43.0")]
94b46f34
XL
372 pub const LOG10_2: f32 = 0.301029995663981195213738894724493027_f32;
373
5bcae85e 374 /// ln(2)
c34b1796 375 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
376 pub const LN_2: f32 = 0.693147180559945309417232121458176568_f32;
377
5bcae85e 378 /// ln(10)
c34b1796 379 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
380 pub const LN_10: f32 = 2.30258509299404568401799145468436421_f32;
381}
382
94b46f34
XL
383#[cfg(not(test))]
384impl f32 {
74b04a01
XL
385 /// The radix or base of the internal representation of `f32`.
386 #[stable(feature = "assoc_int_consts", since = "1.43.0")]
387 pub const RADIX: u32 = 2;
388
389 /// Number of significant digits in base 2.
390 #[stable(feature = "assoc_int_consts", since = "1.43.0")]
391 pub const MANTISSA_DIGITS: u32 = 24;
392
393 /// Approximate number of significant digits in base 10.
ed00b5ec
FG
394 ///
395 /// This is the maximum <i>x</i> such that any decimal number with <i>x</i>
396 /// significant digits can be converted to `f32` and back without loss.
397 ///
398 /// Equal to floor(log<sub>10</sub>&nbsp;2<sup>[`MANTISSA_DIGITS`]&nbsp;&minus;&nbsp;1</sup>).
399 ///
400 /// [`MANTISSA_DIGITS`]: f32::MANTISSA_DIGITS
74b04a01
XL
401 #[stable(feature = "assoc_int_consts", since = "1.43.0")]
402 pub const DIGITS: u32 = 6;
403
404 /// [Machine epsilon] value for `f32`.
405 ///
406 /// This is the difference between `1.0` and the next larger representable number.
407 ///
ed00b5ec
FG
408 /// Equal to 2<sup>1&nbsp;&minus;&nbsp;[`MANTISSA_DIGITS`]</sup>.
409 ///
74b04a01 410 /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon
ed00b5ec 411 /// [`MANTISSA_DIGITS`]: f32::MANTISSA_DIGITS
74b04a01
XL
412 #[stable(feature = "assoc_int_consts", since = "1.43.0")]
413 pub const EPSILON: f32 = 1.19209290e-07_f32;
414
415 /// Smallest finite `f32` value.
ed00b5ec
FG
416 ///
417 /// Equal to &minus;[`MAX`].
418 ///
419 /// [`MAX`]: f32::MAX
74b04a01
XL
420 #[stable(feature = "assoc_int_consts", since = "1.43.0")]
421 pub const MIN: f32 = -3.40282347e+38_f32;
422 /// Smallest positive normal `f32` value.
ed00b5ec
FG
423 ///
424 /// Equal to 2<sup>[`MIN_EXP`]&nbsp;&minus;&nbsp;1</sup>.
425 ///
426 /// [`MIN_EXP`]: f32::MIN_EXP
74b04a01
XL
427 #[stable(feature = "assoc_int_consts", since = "1.43.0")]
428 pub const MIN_POSITIVE: f32 = 1.17549435e-38_f32;
429 /// Largest finite `f32` value.
ed00b5ec
FG
430 ///
431 /// Equal to
432 /// (1&nbsp;&minus;&nbsp;2<sup>&minus;[`MANTISSA_DIGITS`]</sup>)&nbsp;2<sup>[`MAX_EXP`]</sup>.
433 ///
434 /// [`MANTISSA_DIGITS`]: f32::MANTISSA_DIGITS
435 /// [`MAX_EXP`]: f32::MAX_EXP
74b04a01
XL
436 #[stable(feature = "assoc_int_consts", since = "1.43.0")]
437 pub const MAX: f32 = 3.40282347e+38_f32;
438
439 /// One greater than the minimum possible normal power of 2 exponent.
ed00b5ec
FG
440 ///
441 /// If <i>x</i>&nbsp;=&nbsp;`MIN_EXP`, then normal numbers
442 /// ≥&nbsp;0.5&nbsp;×&nbsp;2<sup><i>x</i></sup>.
74b04a01
XL
443 #[stable(feature = "assoc_int_consts", since = "1.43.0")]
444 pub const MIN_EXP: i32 = -125;
445 /// Maximum possible power of 2 exponent.
ed00b5ec
FG
446 ///
447 /// If <i>x</i>&nbsp;=&nbsp;`MAX_EXP`, then normal numbers
448 /// &lt;&nbsp;1&nbsp;×&nbsp;2<sup><i>x</i></sup>.
74b04a01
XL
449 #[stable(feature = "assoc_int_consts", since = "1.43.0")]
450 pub const MAX_EXP: i32 = 128;
451
ed00b5ec
FG
452 /// Minimum <i>x</i> for which 10<sup><i>x</i></sup> is normal.
453 ///
454 /// Equal to ceil(log<sub>10</sub>&nbsp;[`MIN_POSITIVE`]).
455 ///
456 /// [`MIN_POSITIVE`]: f32::MIN_POSITIVE
74b04a01
XL
457 #[stable(feature = "assoc_int_consts", since = "1.43.0")]
458 pub const MIN_10_EXP: i32 = -37;
ed00b5ec
FG
459 /// Maximum <i>x</i> for which 10<sup><i>x</i></sup> is normal.
460 ///
461 /// Equal to floor(log<sub>10</sub>&nbsp;[`MAX`]).
462 ///
463 /// [`MAX`]: f32::MAX
74b04a01
XL
464 #[stable(feature = "assoc_int_consts", since = "1.43.0")]
465 pub const MAX_10_EXP: i32 = 38;
466
467 /// Not a Number (NaN).
04454e1e 468 ///
f2b60f7d 469 /// Note that IEEE 754 doesn't define just a single NaN value;
04454e1e
FG
470 /// a plethora of bit patterns are considered to be NaN.
471 /// Furthermore, the standard makes a difference
472 /// between a "signaling" and a "quiet" NaN,
473 /// and allows inspecting its "payload" (the unspecified bits in the bit pattern).
474 /// This constant isn't guaranteed to equal to any specific NaN bitpattern,
475 /// and the stability of its representation over Rust versions
476 /// and target platforms isn't guaranteed.
74b04a01 477 #[stable(feature = "assoc_int_consts", since = "1.43.0")]
fe692bf9 478 #[rustc_diagnostic_item = "f32_nan"]
c620b35d 479 #[allow(clippy::eq_op)]
74b04a01
XL
480 pub const NAN: f32 = 0.0_f32 / 0.0_f32;
481 /// Infinity (∞).
482 #[stable(feature = "assoc_int_consts", since = "1.43.0")]
483 pub const INFINITY: f32 = 1.0_f32 / 0.0_f32;
f9f354fc 484 /// Negative infinity (−∞).
74b04a01
XL
485 #[stable(feature = "assoc_int_consts", since = "1.43.0")]
486 pub const NEG_INFINITY: f32 = -1.0_f32 / 0.0_f32;
487
04454e1e 488 /// Returns `true` if this value is NaN.
83c7162d
XL
489 ///
490 /// ```
83c7162d
XL
491 /// let nan = f32::NAN;
492 /// let f = 7.0_f32;
493 ///
494 /// assert!(nan.is_nan());
495 /// assert!(!f.is_nan());
496 /// ```
c295e0f8 497 #[must_use]
83c7162d 498 #[stable(feature = "rust1", since = "1.0.0")]
3dfed10e 499 #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
83c7162d 500 #[inline]
c620b35d 501 #[allow(clippy::eq_op)] // > if you intended to check if the operand is NaN, use `.is_nan()` instead :)
3dfed10e 502 pub const fn is_nan(self) -> bool {
94b46f34
XL
503 self != self
504 }
83c7162d 505
9c376795 506 // FIXME(#50145): `abs` is publicly unavailable in core due to
0731742a
XL
507 // concerns about portability, so this implementation is for
508 // private use internally.
509 #[inline]
3dfed10e 510 #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
3c0e092e 511 pub(crate) const fn abs_private(self) -> f32 {
04454e1e
FG
512 // SAFETY: This transmutation is fine. Probably. For the reasons std is using it.
513 unsafe { mem::transmute::<u32, f32>(mem::transmute::<f32, u32>(self) & 0x7fff_ffff) }
0731742a
XL
514 }
515
9fa01778
XL
516 /// Returns `true` if this value is positive infinity or negative infinity, and
517 /// `false` otherwise.
83c7162d
XL
518 ///
519 /// ```
83c7162d
XL
520 /// let f = 7.0f32;
521 /// let inf = f32::INFINITY;
522 /// let neg_inf = f32::NEG_INFINITY;
523 /// let nan = f32::NAN;
524 ///
525 /// assert!(!f.is_infinite());
526 /// assert!(!nan.is_infinite());
527 ///
528 /// assert!(inf.is_infinite());
529 /// assert!(neg_inf.is_infinite());
530 /// ```
c295e0f8 531 #[must_use]
83c7162d 532 #[stable(feature = "rust1", since = "1.0.0")]
3dfed10e 533 #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
83c7162d 534 #[inline]
3dfed10e 535 pub const fn is_infinite(self) -> bool {
04454e1e
FG
536 // Getting clever with transmutation can result in incorrect answers on some FPUs
537 // FIXME: alter the Rust <-> Rust calling convention to prevent this problem.
538 // See https://github.com/rust-lang/rust/issues/72327
539 (self == f32::INFINITY) | (self == f32::NEG_INFINITY)
94b46f34 540 }
83c7162d 541
04454e1e 542 /// Returns `true` if this number is neither infinite nor NaN.
83c7162d
XL
543 ///
544 /// ```
83c7162d
XL
545 /// let f = 7.0f32;
546 /// let inf = f32::INFINITY;
547 /// let neg_inf = f32::NEG_INFINITY;
548 /// let nan = f32::NAN;
549 ///
550 /// assert!(f.is_finite());
551 ///
552 /// assert!(!nan.is_finite());
553 /// assert!(!inf.is_finite());
554 /// assert!(!neg_inf.is_finite());
555 /// ```
c295e0f8 556 #[must_use]
83c7162d 557 #[stable(feature = "rust1", since = "1.0.0")]
3dfed10e 558 #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
83c7162d 559 #[inline]
3dfed10e 560 pub const fn is_finite(self) -> bool {
0731742a
XL
561 // There's no need to handle NaN separately: if self is NaN,
562 // the comparison is not true, exactly as desired.
f9f354fc 563 self.abs_private() < Self::INFINITY
94b46f34 564 }
83c7162d 565
fc512014
XL
566 /// Returns `true` if the number is [subnormal].
567 ///
568 /// ```
fc512014
XL
569 /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
570 /// let max = f32::MAX;
571 /// let lower_than_min = 1.0e-40_f32;
572 /// let zero = 0.0_f32;
573 ///
574 /// assert!(!min.is_subnormal());
575 /// assert!(!max.is_subnormal());
576 ///
577 /// assert!(!zero.is_subnormal());
578 /// assert!(!f32::NAN.is_subnormal());
579 /// assert!(!f32::INFINITY.is_subnormal());
580 /// // Values between `0` and `min` are Subnormal.
581 /// assert!(lower_than_min.is_subnormal());
582 /// ```
583 /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
c295e0f8 584 #[must_use]
cdc7bbd5 585 #[stable(feature = "is_subnormal", since = "1.53.0")]
fc512014
XL
586 #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
587 #[inline]
588 pub const fn is_subnormal(self) -> bool {
589 matches!(self.classify(), FpCategory::Subnormal)
590 }
591
83c7162d 592 /// Returns `true` if the number is neither zero, infinite,
04454e1e 593 /// [subnormal], or NaN.
83c7162d
XL
594 ///
595 /// ```
83c7162d
XL
596 /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
597 /// let max = f32::MAX;
598 /// let lower_than_min = 1.0e-40_f32;
599 /// let zero = 0.0_f32;
600 ///
601 /// assert!(min.is_normal());
602 /// assert!(max.is_normal());
603 ///
604 /// assert!(!zero.is_normal());
605 /// assert!(!f32::NAN.is_normal());
606 /// assert!(!f32::INFINITY.is_normal());
607 /// // Values between `0` and `min` are Subnormal.
608 /// assert!(!lower_than_min.is_normal());
609 /// ```
610 /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
c295e0f8 611 #[must_use]
83c7162d 612 #[stable(feature = "rust1", since = "1.0.0")]
3dfed10e 613 #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
83c7162d 614 #[inline]
3dfed10e
XL
615 pub const fn is_normal(self) -> bool {
616 matches!(self.classify(), FpCategory::Normal)
94b46f34 617 }
83c7162d
XL
618
619 /// Returns the floating point category of the number. If only one property
620 /// is going to be tested, it is generally faster to use the specific
621 /// predicate instead.
622 ///
623 /// ```
624 /// use std::num::FpCategory;
83c7162d
XL
625 ///
626 /// let num = 12.4_f32;
627 /// let inf = f32::INFINITY;
628 ///
629 /// assert_eq!(num.classify(), FpCategory::Normal);
630 /// assert_eq!(inf.classify(), FpCategory::Infinite);
631 /// ```
632 #[stable(feature = "rust1", since = "1.0.0")]
3dfed10e
XL
633 #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
634 pub const fn classify(self) -> FpCategory {
04454e1e
FG
635 // A previous implementation tried to only use bitmask-based checks,
636 // using f32::to_bits to transmute the float to its bit repr and match on that.
637 // Unfortunately, floating point numbers can be much worse than that.
638 // This also needs to not result in recursive evaluations of f64::to_bits.
639 //
640 // On some processors, in some cases, LLVM will "helpfully" lower floating point ops,
641 // in spite of a request for them using f32 and f64, to things like x87 operations.
642 // These have an f64's mantissa, but can have a larger than normal exponent.
643 // FIXME(jubilee): Using x87 operations is never necessary in order to function
644 // on x86 processors for Rust-to-Rust calls, so this issue should not happen.
645 // Code generation should be adjusted to use non-C calling conventions, avoiding this.
646 //
647 if self.is_infinite() {
648 // Thus, a value may compare unequal to infinity, despite having a "full" exponent mask.
649 FpCategory::Infinite
650 } else if self.is_nan() {
651 // And it may not be NaN, as it can simply be an "overextended" finite value.
652 FpCategory::Nan
653 } else {
654 // However, std can't simply compare to zero to check for zero, either,
655 // as correctness requires avoiding equality tests that may be Subnormal == -0.0
656 // because it may be wrong under "denormals are zero" and "flush to zero" modes.
657 // Most of std's targets don't use those, but they are used for thumbv7neon.
658 // So, this does use bitpattern matching for the rest.
659
660 // SAFETY: f32 to u32 is fine. Usually.
661 // If classify has gotten this far, the value is definitely in one of these categories.
662 unsafe { f32::partial_classify(self) }
663 }
664 }
665
666 // This doesn't actually return a right answer for NaN on purpose,
667 // seeing as how it cannot correctly discern between a floating point NaN,
668 // and some normal floating point numbers truncated from an x87 FPU.
669 // FIXME(jubilee): This probably could at least answer things correctly for Infinity,
670 // like the f64 version does, but I need to run more checks on how things go on x86.
671 // I fear losing mantissa data that would have answered that differently.
672 //
673 // # Safety
674 // This requires making sure you call this function for values it answers correctly on,
675 // otherwise it returns a wrong answer. This is not important for memory safety per se,
676 // but getting floats correct is important for not accidentally leaking const eval
677 // runtime-deviating logic which may or may not be acceptable.
678 #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
679 const unsafe fn partial_classify(self) -> FpCategory {
94b46f34
XL
680 const EXP_MASK: u32 = 0x7f800000;
681 const MAN_MASK: u32 = 0x007fffff;
682
04454e1e
FG
683 // SAFETY: The caller is not asking questions for which this will tell lies.
684 let b = unsafe { mem::transmute::<f32, u32>(self) };
685 match (b & MAN_MASK, b & EXP_MASK) {
94b46f34
XL
686 (0, 0) => FpCategory::Zero,
687 (_, 0) => FpCategory::Subnormal,
04454e1e
FG
688 _ => FpCategory::Normal,
689 }
690 }
691
692 // This operates on bits, and only bits, so it can ignore concerns about weird FPUs.
693 // FIXME(jubilee): In a just world, this would be the entire impl for classify,
694 // plus a transmute. We do not live in a just world, but we can make it more so.
695 #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
696 const fn classify_bits(b: u32) -> FpCategory {
697 const EXP_MASK: u32 = 0x7f800000;
698 const MAN_MASK: u32 = 0x007fffff;
699
700 match (b & MAN_MASK, b & EXP_MASK) {
94b46f34
XL
701 (0, EXP_MASK) => FpCategory::Infinite,
702 (_, EXP_MASK) => FpCategory::Nan,
04454e1e
FG
703 (0, 0) => FpCategory::Zero,
704 (_, 0) => FpCategory::Subnormal,
94b46f34
XL
705 _ => FpCategory::Normal,
706 }
707 }
83c7162d 708
04454e1e 709 /// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with
f2b60f7d 710 /// positive sign bit and positive infinity. Note that IEEE 754 doesn't assign any
04454e1e
FG
711 /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
712 /// the bit pattern of NaNs are conserved over arithmetic operations, the result of
713 /// `is_sign_positive` on a NaN might produce an unexpected result in some cases.
714 /// See [explanation of NaN as a special value](f32) for more info.
83c7162d
XL
715 ///
716 /// ```
717 /// let f = 7.0_f32;
718 /// let g = -7.0_f32;
719 ///
720 /// assert!(f.is_sign_positive());
721 /// assert!(!g.is_sign_positive());
722 /// ```
c295e0f8 723 #[must_use]
83c7162d 724 #[stable(feature = "rust1", since = "1.0.0")]
3dfed10e 725 #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
83c7162d 726 #[inline]
3dfed10e 727 pub const fn is_sign_positive(self) -> bool {
94b46f34
XL
728 !self.is_sign_negative()
729 }
83c7162d 730
04454e1e 731 /// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with
f2b60f7d 732 /// negative sign bit and negative infinity. Note that IEEE 754 doesn't assign any
04454e1e
FG
733 /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
734 /// the bit pattern of NaNs are conserved over arithmetic operations, the result of
735 /// `is_sign_negative` on a NaN might produce an unexpected result in some cases.
736 /// See [explanation of NaN as a special value](f32) for more info.
83c7162d
XL
737 ///
738 /// ```
739 /// let f = 7.0f32;
740 /// let g = -7.0f32;
741 ///
742 /// assert!(!f.is_sign_negative());
743 /// assert!(g.is_sign_negative());
744 /// ```
c295e0f8 745 #[must_use]
83c7162d 746 #[stable(feature = "rust1", since = "1.0.0")]
3dfed10e 747 #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
83c7162d 748 #[inline]
3dfed10e 749 pub const fn is_sign_negative(self) -> bool {
94b46f34
XL
750 // IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus
751 // applies to zeros and NaNs as well.
04454e1e
FG
752 // SAFETY: This is just transmuting to get the sign bit, it's fine.
753 unsafe { mem::transmute::<f32, u32>(self) & 0x8000_0000 != 0 }
94b46f34 754 }
83c7162d 755
f2b60f7d
FG
756 /// Returns the least number greater than `self`.
757 ///
758 /// Let `TINY` be the smallest representable positive `f32`. Then,
759 /// - if `self.is_nan()`, this returns `self`;
760 /// - if `self` is [`NEG_INFINITY`], this returns [`MIN`];
761 /// - if `self` is `-TINY`, this returns -0.0;
762 /// - if `self` is -0.0 or +0.0, this returns `TINY`;
763 /// - if `self` is [`MAX`] or [`INFINITY`], this returns [`INFINITY`];
764 /// - otherwise the unique least value greater than `self` is returned.
765 ///
766 /// The identity `x.next_up() == -(-x).next_down()` holds for all non-NaN `x`. When `x`
767 /// is finite `x == x.next_up().next_down()` also holds.
768 ///
769 /// ```rust
770 /// #![feature(float_next_up_down)]
771 /// // f32::EPSILON is the difference between 1.0 and the next number up.
772 /// assert_eq!(1.0f32.next_up(), 1.0 + f32::EPSILON);
773 /// // But not for most numbers.
774 /// assert!(0.1f32.next_up() < 0.1 + f32::EPSILON);
775 /// assert_eq!(16777216f32.next_up(), 16777218.0);
776 /// ```
777 ///
778 /// [`NEG_INFINITY`]: Self::NEG_INFINITY
779 /// [`INFINITY`]: Self::INFINITY
780 /// [`MIN`]: Self::MIN
781 /// [`MAX`]: Self::MAX
782 #[unstable(feature = "float_next_up_down", issue = "91399")]
783 #[rustc_const_unstable(feature = "float_next_up_down", issue = "91399")]
784 pub const fn next_up(self) -> Self {
785 // We must use strictly integer arithmetic to prevent denormals from
786 // flushing to zero after an arithmetic operation on some platforms.
787 const TINY_BITS: u32 = 0x1; // Smallest positive f32.
788 const CLEAR_SIGN_MASK: u32 = 0x7fff_ffff;
789
790 let bits = self.to_bits();
791 if self.is_nan() || bits == Self::INFINITY.to_bits() {
792 return self;
793 }
794
795 let abs = bits & CLEAR_SIGN_MASK;
796 let next_bits = if abs == 0 {
797 TINY_BITS
798 } else if bits == abs {
799 bits + 1
800 } else {
801 bits - 1
802 };
803 Self::from_bits(next_bits)
804 }
805
806 /// Returns the greatest number less than `self`.
807 ///
808 /// Let `TINY` be the smallest representable positive `f32`. Then,
809 /// - if `self.is_nan()`, this returns `self`;
810 /// - if `self` is [`INFINITY`], this returns [`MAX`];
811 /// - if `self` is `TINY`, this returns 0.0;
812 /// - if `self` is -0.0 or +0.0, this returns `-TINY`;
813 /// - if `self` is [`MIN`] or [`NEG_INFINITY`], this returns [`NEG_INFINITY`];
814 /// - otherwise the unique greatest value less than `self` is returned.
815 ///
816 /// The identity `x.next_down() == -(-x).next_up()` holds for all non-NaN `x`. When `x`
817 /// is finite `x == x.next_down().next_up()` also holds.
818 ///
819 /// ```rust
820 /// #![feature(float_next_up_down)]
821 /// let x = 1.0f32;
822 /// // Clamp value into range [0, 1).
823 /// let clamped = x.clamp(0.0, 1.0f32.next_down());
824 /// assert!(clamped < 1.0);
825 /// assert_eq!(clamped.next_up(), 1.0);
826 /// ```
827 ///
828 /// [`NEG_INFINITY`]: Self::NEG_INFINITY
829 /// [`INFINITY`]: Self::INFINITY
830 /// [`MIN`]: Self::MIN
831 /// [`MAX`]: Self::MAX
832 #[unstable(feature = "float_next_up_down", issue = "91399")]
833 #[rustc_const_unstable(feature = "float_next_up_down", issue = "91399")]
834 pub const fn next_down(self) -> Self {
835 // We must use strictly integer arithmetic to prevent denormals from
836 // flushing to zero after an arithmetic operation on some platforms.
837 const NEG_TINY_BITS: u32 = 0x8000_0001; // Smallest (in magnitude) negative f32.
838 const CLEAR_SIGN_MASK: u32 = 0x7fff_ffff;
839
840 let bits = self.to_bits();
841 if self.is_nan() || bits == Self::NEG_INFINITY.to_bits() {
842 return self;
843 }
844
845 let abs = bits & CLEAR_SIGN_MASK;
846 let next_bits = if abs == 0 {
847 NEG_TINY_BITS
848 } else if bits == abs {
849 bits - 1
850 } else {
851 bits + 1
852 };
853 Self::from_bits(next_bits)
854 }
855
83c7162d
XL
856 /// Takes the reciprocal (inverse) of a number, `1/x`.
857 ///
858 /// ```
83c7162d 859 /// let x = 2.0_f32;
e1599b0c 860 /// let abs_difference = (x.recip() - (1.0 / x)).abs();
83c7162d
XL
861 ///
862 /// assert!(abs_difference <= f32::EPSILON);
863 /// ```
a2a8927a 864 #[must_use = "this returns the result of the operation, without modifying the original"]
83c7162d
XL
865 #[stable(feature = "rust1", since = "1.0.0")]
866 #[inline]
94b46f34
XL
867 pub fn recip(self) -> f32 {
868 1.0 / self
869 }
83c7162d
XL
870
871 /// Converts radians to degrees.
872 ///
873 /// ```
ba9703b0 874 /// let angle = std::f32::consts::PI;
83c7162d
XL
875 ///
876 /// let abs_difference = (angle.to_degrees() - 180.0).abs();
ed00b5ec 877 /// # #[cfg(any(not(target_arch = "x86"), target_feature = "sse2"))]
83c7162d
XL
878 /// assert!(abs_difference <= f32::EPSILON);
879 /// ```
c295e0f8
XL
880 #[must_use = "this returns the result of the operation, \
881 without modifying the original"]
dfeec247 882 #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")]
83c7162d 883 #[inline]
94b46f34
XL
884 pub fn to_degrees(self) -> f32 {
885 // Use a constant for better precision.
886 const PIS_IN_180: f32 = 57.2957795130823208767981548141051703_f32;
887 self * PIS_IN_180
888 }
83c7162d
XL
889
890 /// Converts degrees to radians.
891 ///
892 /// ```
83c7162d
XL
893 /// let angle = 180.0f32;
894 ///
ba9703b0 895 /// let abs_difference = (angle.to_radians() - std::f32::consts::PI).abs();
83c7162d
XL
896 ///
897 /// assert!(abs_difference <= f32::EPSILON);
898 /// ```
c295e0f8
XL
899 #[must_use = "this returns the result of the operation, \
900 without modifying the original"]
dfeec247 901 #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")]
83c7162d 902 #[inline]
94b46f34
XL
903 pub fn to_radians(self) -> f32 {
904 let value: f32 = consts::PI;
905 self * (value / 180.0f32)
906 }
83c7162d 907
04454e1e 908 /// Returns the maximum of the two numbers, ignoring NaN.
83c7162d 909 ///
04454e1e 910 /// If one of the arguments is NaN, then the other argument is returned.
f2b60f7d 911 /// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs;
04454e1e
FG
912 /// this function handles all NaNs the same way and avoids maxNum's problems with associativity.
913 /// This also matches the behavior of libm’s fmax.
3c0e092e 914 ///
83c7162d
XL
915 /// ```
916 /// let x = 1.0f32;
917 /// let y = 2.0f32;
918 ///
919 /// assert_eq!(x.max(y), y);
920 /// ```
a2a8927a 921 #[must_use = "this returns the result of the comparison, without modifying either input"]
83c7162d
XL
922 #[stable(feature = "rust1", since = "1.0.0")]
923 #[inline]
924 pub fn max(self, other: f32) -> f32 {
dc9dc135 925 intrinsics::maxnumf32(self, other)
83c7162d
XL
926 }
927
04454e1e 928 /// Returns the minimum of the two numbers, ignoring NaN.
83c7162d 929 ///
04454e1e 930 /// If one of the arguments is NaN, then the other argument is returned.
f2b60f7d 931 /// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs;
04454e1e
FG
932 /// this function handles all NaNs the same way and avoids minNum's problems with associativity.
933 /// This also matches the behavior of libm’s fmin.
3c0e092e 934 ///
83c7162d
XL
935 /// ```
936 /// let x = 1.0f32;
937 /// let y = 2.0f32;
938 ///
939 /// assert_eq!(x.min(y), x);
940 /// ```
a2a8927a 941 #[must_use = "this returns the result of the comparison, without modifying either input"]
83c7162d
XL
942 #[stable(feature = "rust1", since = "1.0.0")]
943 #[inline]
944 pub fn min(self, other: f32) -> f32 {
dc9dc135 945 intrinsics::minnumf32(self, other)
83c7162d
XL
946 }
947
04454e1e 948 /// Returns the maximum of the two numbers, propagating NaN.
3c0e092e
XL
949 ///
950 /// This returns NaN when *either* argument is NaN, as opposed to
951 /// [`f32::max`] which only returns NaN when *both* arguments are NaN.
952 ///
953 /// ```
954 /// #![feature(float_minimum_maximum)]
955 /// let x = 1.0f32;
956 /// let y = 2.0f32;
957 ///
958 /// assert_eq!(x.maximum(y), y);
959 /// assert!(x.maximum(f32::NAN).is_nan());
960 /// ```
961 ///
962 /// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the greater
963 /// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.
964 /// Note that this follows the semantics specified in IEEE 754-2019.
04454e1e
FG
965 ///
966 /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN
967 /// operand is conserved; see [explanation of NaN as a special value](f32) for more info.
a2a8927a 968 #[must_use = "this returns the result of the comparison, without modifying either input"]
3c0e092e
XL
969 #[unstable(feature = "float_minimum_maximum", issue = "91079")]
970 #[inline]
971 pub fn maximum(self, other: f32) -> f32 {
972 if self > other {
973 self
974 } else if other > self {
975 other
976 } else if self == other {
977 if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
978 } else {
979 self + other
980 }
981 }
982
04454e1e 983 /// Returns the minimum of the two numbers, propagating NaN.
3c0e092e
XL
984 ///
985 /// This returns NaN when *either* argument is NaN, as opposed to
986 /// [`f32::min`] which only returns NaN when *both* arguments are NaN.
987 ///
988 /// ```
989 /// #![feature(float_minimum_maximum)]
990 /// let x = 1.0f32;
991 /// let y = 2.0f32;
992 ///
993 /// assert_eq!(x.minimum(y), x);
994 /// assert!(x.minimum(f32::NAN).is_nan());
995 /// ```
996 ///
997 /// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the lesser
998 /// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.
999 /// Note that this follows the semantics specified in IEEE 754-2019.
04454e1e
FG
1000 ///
1001 /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN
1002 /// operand is conserved; see [explanation of NaN as a special value](f32) for more info.
a2a8927a 1003 #[must_use = "this returns the result of the comparison, without modifying either input"]
3c0e092e
XL
1004 #[unstable(feature = "float_minimum_maximum", issue = "91079")]
1005 #[inline]
1006 pub fn minimum(self, other: f32) -> f32 {
1007 if self < other {
1008 self
1009 } else if other < self {
1010 other
1011 } else if self == other {
1012 if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
1013 } else {
781aab86 1014 // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
3c0e092e
XL
1015 self + other
1016 }
1017 }
1018
49aad941
FG
1019 /// Calculates the middle point of `self` and `rhs`.
1020 ///
1021 /// This returns NaN when *either* argument is NaN or if a combination of
1022 /// +inf and -inf is provided as arguments.
1023 ///
1024 /// # Examples
1025 ///
1026 /// ```
1027 /// #![feature(num_midpoint)]
1028 /// assert_eq!(1f32.midpoint(4.0), 2.5);
1029 /// assert_eq!((-5.5f32).midpoint(8.0), 1.25);
1030 /// ```
1031 #[unstable(feature = "num_midpoint", issue = "110840")]
1032 pub fn midpoint(self, other: f32) -> f32 {
1033 const LO: f32 = f32::MIN_POSITIVE * 2.;
1034 const HI: f32 = f32::MAX / 2.;
1035
1036 let (a, b) = (self, other);
1037 let abs_a = a.abs_private();
1038 let abs_b = b.abs_private();
1039
1040 if abs_a <= HI && abs_b <= HI {
1041 // Overflow is impossible
1042 (a + b) / 2.
1043 } else if abs_a < LO {
1044 // Not safe to halve a
1045 a + (b / 2.)
1046 } else if abs_b < LO {
1047 // Not safe to halve b
1048 (a / 2.) + b
1049 } else {
1050 // Not safe to halve a and b
1051 (a / 2.) + (b / 2.)
1052 }
1053 }
1054
60c5eb7d
XL
1055 /// Rounds toward zero and converts to any primitive integer type,
1056 /// assuming that the value is finite and fits in that type.
1057 ///
1058 /// ```
60c5eb7d 1059 /// let value = 4.6_f32;
ba9703b0 1060 /// let rounded = unsafe { value.to_int_unchecked::<u16>() };
60c5eb7d
XL
1061 /// assert_eq!(rounded, 4);
1062 ///
1063 /// let value = -128.9_f32;
ba9703b0
XL
1064 /// let rounded = unsafe { value.to_int_unchecked::<i8>() };
1065 /// assert_eq!(rounded, i8::MIN);
60c5eb7d
XL
1066 /// ```
1067 ///
1068 /// # Safety
1069 ///
1070 /// The value must:
1071 ///
1072 /// * Not be `NaN`
1073 /// * Not be infinite
1074 /// * Be representable in the return type `Int`, after truncating off its fractional part
c295e0f8
XL
1075 #[must_use = "this returns the result of the operation, \
1076 without modifying the original"]
ba9703b0 1077 #[stable(feature = "float_approx_unchecked_to", since = "1.44.0")]
60c5eb7d 1078 #[inline]
ba9703b0 1079 pub unsafe fn to_int_unchecked<Int>(self) -> Int
dfeec247
XL
1080 where
1081 Self: FloatToInt<Int>,
1082 {
f035d41b
XL
1083 // SAFETY: the caller must uphold the safety contract for
1084 // `FloatToInt::to_int_unchecked`.
1085 unsafe { FloatToInt::<Int>::to_int_unchecked(self) }
60c5eb7d
XL
1086 }
1087
83c7162d
XL
1088 /// Raw transmutation to `u32`.
1089 ///
1090 /// This is currently identical to `transmute::<f32, u32>(self)` on all platforms.
1091 ///
17df50a5
XL
1092 /// See [`from_bits`](Self::from_bits) for some discussion of the
1093 /// portability of this operation (there are almost no issues).
83c7162d
XL
1094 ///
1095 /// Note that this function is distinct from `as` casting, which attempts to
1096 /// preserve the *numeric* value, and not the bitwise value.
1097 ///
1098 /// # Examples
1099 ///
1100 /// ```
1101 /// assert_ne!((1f32).to_bits(), 1f32 as u32); // to_bits() is not casting!
1102 /// assert_eq!((12.5f32).to_bits(), 0x41480000);
1103 ///
1104 /// ```
c295e0f8
XL
1105 #[must_use = "this returns the result of the operation, \
1106 without modifying the original"]
83c7162d 1107 #[stable(feature = "float_bits_conv", since = "1.20.0")]
3dfed10e 1108 #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
83c7162d 1109 #[inline]
3dfed10e 1110 pub const fn to_bits(self) -> u32 {
04454e1e
FG
1111 // SAFETY: `u32` is a plain old datatype so we can always transmute to it.
1112 // ...sorta.
1113 //
1114 // It turns out that at runtime, it is possible for a floating point number
1115 // to be subject to a floating point mode that alters nonzero subnormal numbers
1116 // to zero on reads and writes, aka "denormals are zero" and "flush to zero".
1117 // This is not a problem per se, but at least one tier2 platform for Rust
1118 // actually exhibits this behavior by default.
1119 //
1120 // In addition, on x86 targets with SSE or SSE2 disabled and the x87 FPU enabled,
1121 // i.e. not soft-float, the way Rust does parameter passing can actually alter
1122 // a number that is "not infinity" to have the same exponent as infinity,
1123 // in a slightly unpredictable manner.
1124 //
1125 // And, of course evaluating to a NaN value is fairly nondeterministic.
1126 // More precisely: when NaN should be returned is knowable, but which NaN?
1127 // So far that's defined by a combination of LLVM and the CPU, not Rust.
1128 // This function, however, allows observing the bitstring of a NaN,
1129 // thus introspection on CTFE.
1130 //
1131 // In order to preserve, at least for the moment, const-to-runtime equivalence,
1132 // we reject any of these possible situations from happening.
1133 #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
1134 const fn ct_f32_to_u32(ct: f32) -> u32 {
1135 match ct.classify() {
1136 FpCategory::Nan => {
1137 panic!("const-eval error: cannot use f32::to_bits on a NaN")
1138 }
1139 FpCategory::Subnormal => {
1140 panic!("const-eval error: cannot use f32::to_bits on a subnormal number")
1141 }
1142 FpCategory::Infinite | FpCategory::Normal | FpCategory::Zero => {
1143 // SAFETY: We have a normal floating point number. Now we transmute, i.e. do a bitcopy.
1144 unsafe { mem::transmute::<f32, u32>(ct) }
1145 }
1146 }
1147 }
f2b60f7d
FG
1148
1149 #[inline(always)] // See https://github.com/rust-lang/compiler-builtins/issues/491
1150 fn rt_f32_to_u32(x: f32) -> u32 {
1151 // SAFETY: `u32` is a plain old datatype so we can always... uh...
1152 // ...look, just pretend you forgot what you just read.
1153 // Stability concerns.
1154 unsafe { mem::transmute(x) }
1155 }
e8be2606 1156 intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32)
83c7162d
XL
1157 }
1158
1159 /// Raw transmutation from `u32`.
1160 ///
1161 /// This is currently identical to `transmute::<u32, f32>(v)` on all platforms.
1162 /// It turns out this is incredibly portable, for two reasons:
1163 ///
1164 /// * Floats and Ints have the same endianness on all supported platforms.
f2b60f7d 1165 /// * IEEE 754 very precisely specifies the bit layout of floats.
83c7162d 1166 ///
f2b60f7d 1167 /// However there is one caveat: prior to the 2008 version of IEEE 754, how
83c7162d
XL
1168 /// to interpret the NaN signaling bit wasn't actually specified. Most platforms
1169 /// (notably x86 and ARM) picked the interpretation that was ultimately
1170 /// standardized in 2008, but some didn't (notably MIPS). As a result, all
1171 /// signaling NaNs on MIPS are quiet NaNs on x86, and vice-versa.
1172 ///
1173 /// Rather than trying to preserve signaling-ness cross-platform, this
a1dfa0c6 1174 /// implementation favors preserving the exact bits. This means that
83c7162d
XL
1175 /// any payloads encoded in NaNs will be preserved even if the result of
1176 /// this method is sent over the network from an x86 machine to a MIPS one.
1177 ///
1178 /// If the results of this method are only manipulated by the same
1179 /// architecture that produced them, then there is no portability concern.
1180 ///
1181 /// If the input isn't NaN, then there is no portability concern.
1182 ///
1183 /// If you don't care about signalingness (very likely), then there is no
1184 /// portability concern.
1185 ///
1186 /// Note that this function is distinct from `as` casting, which attempts to
1187 /// preserve the *numeric* value, and not the bitwise value.
1188 ///
1189 /// # Examples
1190 ///
1191 /// ```
83c7162d 1192 /// let v = f32::from_bits(0x41480000);
416331ca 1193 /// assert_eq!(v, 12.5);
83c7162d
XL
1194 /// ```
1195 #[stable(feature = "float_bits_conv", since = "1.20.0")]
3dfed10e 1196 #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
c295e0f8 1197 #[must_use]
83c7162d 1198 #[inline]
3dfed10e 1199 pub const fn from_bits(v: u32) -> Self {
94b46f34 1200 // It turns out the safety issues with sNaN were overblown! Hooray!
04454e1e
FG
1201 // SAFETY: `u32` is a plain old datatype so we can always transmute from it
1202 // ...sorta.
1203 //
1204 // It turns out that at runtime, it is possible for a floating point number
1205 // to be subject to floating point modes that alter nonzero subnormal numbers
1206 // to zero on reads and writes, aka "denormals are zero" and "flush to zero".
1207 // This is not a problem usually, but at least one tier2 platform for Rust
1208 // actually exhibits this behavior by default: thumbv7neon
1209 // aka "the Neon FPU in AArch32 state"
1210 //
1211 // In addition, on x86 targets with SSE or SSE2 disabled and the x87 FPU enabled,
1212 // i.e. not soft-float, the way Rust does parameter passing can actually alter
1213 // a number that is "not infinity" to have the same exponent as infinity,
1214 // in a slightly unpredictable manner.
1215 //
1216 // And, of course evaluating to a NaN value is fairly nondeterministic.
1217 // More precisely: when NaN should be returned is knowable, but which NaN?
1218 // So far that's defined by a combination of LLVM and the CPU, not Rust.
1219 // This function, however, allows observing the bitstring of a NaN,
1220 // thus introspection on CTFE.
1221 //
1222 // In order to preserve, at least for the moment, const-to-runtime equivalence,
1223 // reject any of these possible situations from happening.
1224 #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
1225 const fn ct_u32_to_f32(ct: u32) -> f32 {
1226 match f32::classify_bits(ct) {
1227 FpCategory::Subnormal => {
1228 panic!("const-eval error: cannot use f32::from_bits on a subnormal number")
1229 }
1230 FpCategory::Nan => {
1231 panic!("const-eval error: cannot use f32::from_bits on NaN")
1232 }
1233 FpCategory::Infinite | FpCategory::Normal | FpCategory::Zero => {
1234 // SAFETY: It's not a frumious number
1235 unsafe { mem::transmute::<u32, f32>(ct) }
1236 }
1237 }
1238 }
f2b60f7d
FG
1239
1240 #[inline(always)] // See https://github.com/rust-lang/compiler-builtins/issues/491
1241 fn rt_u32_to_f32(x: u32) -> f32 {
1242 // SAFETY: `u32` is a plain old datatype so we can always... uh...
1243 // ...look, just pretend you forgot what you just read.
1244 // Stability concerns.
1245 unsafe { mem::transmute(x) }
1246 }
e8be2606 1247 intrinsics::const_eval_select((v,), ct_u32_to_f32, rt_u32_to_f32)
83c7162d 1248 }
416331ca
XL
1249
1250 /// Return the memory representation of this floating point number as a byte array in
1251 /// big-endian (network) byte order.
1252 ///
04454e1e
FG
1253 /// See [`from_bits`](Self::from_bits) for some discussion of the
1254 /// portability of this operation (there are almost no issues).
1255 ///
416331ca
XL
1256 /// # Examples
1257 ///
1258 /// ```
416331ca
XL
1259 /// let bytes = 12.5f32.to_be_bytes();
1260 /// assert_eq!(bytes, [0x41, 0x48, 0x00, 0x00]);
1261 /// ```
c295e0f8
XL
1262 #[must_use = "this returns the result of the operation, \
1263 without modifying the original"]
e74abb32 1264 #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
3dfed10e 1265 #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
416331ca 1266 #[inline]
3dfed10e 1267 pub const fn to_be_bytes(self) -> [u8; 4] {
416331ca
XL
1268 self.to_bits().to_be_bytes()
1269 }
1270
1271 /// Return the memory representation of this floating point number as a byte array in
1272 /// little-endian byte order.
1273 ///
04454e1e
FG
1274 /// See [`from_bits`](Self::from_bits) for some discussion of the
1275 /// portability of this operation (there are almost no issues).
1276 ///
416331ca
XL
1277 /// # Examples
1278 ///
1279 /// ```
416331ca
XL
1280 /// let bytes = 12.5f32.to_le_bytes();
1281 /// assert_eq!(bytes, [0x00, 0x00, 0x48, 0x41]);
1282 /// ```
c295e0f8
XL
1283 #[must_use = "this returns the result of the operation, \
1284 without modifying the original"]
e74abb32 1285 #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
3dfed10e 1286 #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
416331ca 1287 #[inline]
3dfed10e 1288 pub const fn to_le_bytes(self) -> [u8; 4] {
416331ca
XL
1289 self.to_bits().to_le_bytes()
1290 }
1291
1292 /// Return the memory representation of this floating point number as a byte array in
1293 /// native byte order.
1294 ///
1295 /// As the target platform's native endianness is used, portable code
1296 /// should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, instead.
1297 ///
6a06907d
XL
1298 /// [`to_be_bytes`]: f32::to_be_bytes
1299 /// [`to_le_bytes`]: f32::to_le_bytes
416331ca 1300 ///
04454e1e
FG
1301 /// See [`from_bits`](Self::from_bits) for some discussion of the
1302 /// portability of this operation (there are almost no issues).
1303 ///
416331ca
XL
1304 /// # Examples
1305 ///
1306 /// ```
416331ca
XL
1307 /// let bytes = 12.5f32.to_ne_bytes();
1308 /// assert_eq!(
1309 /// bytes,
1310 /// if cfg!(target_endian = "big") {
1311 /// [0x41, 0x48, 0x00, 0x00]
1312 /// } else {
1313 /// [0x00, 0x00, 0x48, 0x41]
1314 /// }
1315 /// );
1316 /// ```
c295e0f8
XL
1317 #[must_use = "this returns the result of the operation, \
1318 without modifying the original"]
e74abb32 1319 #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
3dfed10e 1320 #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
416331ca 1321 #[inline]
3dfed10e 1322 pub const fn to_ne_bytes(self) -> [u8; 4] {
416331ca
XL
1323 self.to_bits().to_ne_bytes()
1324 }
1325
1326 /// Create a floating point value from its representation as a byte array in big endian.
1327 ///
04454e1e
FG
1328 /// See [`from_bits`](Self::from_bits) for some discussion of the
1329 /// portability of this operation (there are almost no issues).
1330 ///
416331ca
XL
1331 /// # Examples
1332 ///
1333 /// ```
416331ca
XL
1334 /// let value = f32::from_be_bytes([0x41, 0x48, 0x00, 0x00]);
1335 /// assert_eq!(value, 12.5);
1336 /// ```
e74abb32 1337 #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
3dfed10e 1338 #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
c295e0f8 1339 #[must_use]
416331ca 1340 #[inline]
3dfed10e 1341 pub const fn from_be_bytes(bytes: [u8; 4]) -> Self {
416331ca
XL
1342 Self::from_bits(u32::from_be_bytes(bytes))
1343 }
1344
1345 /// Create a floating point value from its representation as a byte array in little endian.
1346 ///
04454e1e
FG
1347 /// See [`from_bits`](Self::from_bits) for some discussion of the
1348 /// portability of this operation (there are almost no issues).
1349 ///
416331ca
XL
1350 /// # Examples
1351 ///
1352 /// ```
416331ca
XL
1353 /// let value = f32::from_le_bytes([0x00, 0x00, 0x48, 0x41]);
1354 /// assert_eq!(value, 12.5);
1355 /// ```
e74abb32 1356 #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
3dfed10e 1357 #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
c295e0f8 1358 #[must_use]
416331ca 1359 #[inline]
3dfed10e 1360 pub const fn from_le_bytes(bytes: [u8; 4]) -> Self {
416331ca
XL
1361 Self::from_bits(u32::from_le_bytes(bytes))
1362 }
1363
1364 /// Create a floating point value from its representation as a byte array in native endian.
1365 ///
1366 /// As the target platform's native endianness is used, portable code
1367 /// likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as
1368 /// appropriate instead.
1369 ///
6a06907d
XL
1370 /// [`from_be_bytes`]: f32::from_be_bytes
1371 /// [`from_le_bytes`]: f32::from_le_bytes
416331ca 1372 ///
04454e1e
FG
1373 /// See [`from_bits`](Self::from_bits) for some discussion of the
1374 /// portability of this operation (there are almost no issues).
1375 ///
416331ca
XL
1376 /// # Examples
1377 ///
1378 /// ```
416331ca
XL
1379 /// let value = f32::from_ne_bytes(if cfg!(target_endian = "big") {
1380 /// [0x41, 0x48, 0x00, 0x00]
1381 /// } else {
1382 /// [0x00, 0x00, 0x48, 0x41]
1383 /// });
1384 /// assert_eq!(value, 12.5);
1385 /// ```
e74abb32 1386 #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
3dfed10e 1387 #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
c295e0f8 1388 #[must_use]
416331ca 1389 #[inline]
3dfed10e 1390 pub const fn from_ne_bytes(bytes: [u8; 4]) -> Self {
416331ca
XL
1391 Self::from_bits(u32::from_ne_bytes(bytes))
1392 }
f9f354fc 1393
5099ac24
FG
1394 /// Return the ordering between `self` and `other`.
1395 ///
f9f354fc
XL
1396 /// Unlike the standard partial comparison between floating point numbers,
1397 /// this comparison always produces an ordering in accordance to
5099ac24
FG
1398 /// the `totalOrder` predicate as defined in the IEEE 754 (2008 revision)
1399 /// floating point standard. The values are ordered in the following sequence:
1400 ///
1401 /// - negative quiet NaN
1402 /// - negative signaling NaN
1403 /// - negative infinity
1404 /// - negative numbers
1405 /// - negative subnormal numbers
1406 /// - negative zero
1407 /// - positive zero
1408 /// - positive subnormal numbers
1409 /// - positive numbers
1410 /// - positive infinity
1411 /// - positive signaling NaN
1412 /// - positive quiet NaN.
1413 ///
1414 /// The ordering established by this function does not always agree with the
1415 /// [`PartialOrd`] and [`PartialEq`] implementations of `f32`. For example,
1416 /// they consider negative and positive zero equal, while `total_cmp`
1417 /// doesn't.
1418 ///
1419 /// The interpretation of the signaling NaN bit follows the definition in
1420 /// the IEEE 754 standard, which may not match the interpretation by some of
1421 /// the older, non-conformant (e.g. MIPS) hardware implementations.
29967ef6 1422 ///
f9f354fc 1423 /// # Example
5099ac24 1424 ///
f9f354fc 1425 /// ```
f9f354fc
XL
1426 /// struct GoodBoy {
1427 /// name: String,
1428 /// weight: f32,
1429 /// }
1430 ///
1431 /// let mut bois = vec![
1432 /// GoodBoy { name: "Pucci".to_owned(), weight: 0.1 },
1433 /// GoodBoy { name: "Woofer".to_owned(), weight: 99.0 },
1434 /// GoodBoy { name: "Yapper".to_owned(), weight: 10.0 },
1435 /// GoodBoy { name: "Chonk".to_owned(), weight: f32::INFINITY },
1436 /// GoodBoy { name: "Abs. Unit".to_owned(), weight: f32::NAN },
1437 /// GoodBoy { name: "Floaty".to_owned(), weight: -5.0 },
1438 /// ];
1439 ///
1440 /// bois.sort_by(|a, b| a.weight.total_cmp(&b.weight));
4b012472
FG
1441 ///
1442 /// // `f32::NAN` could be positive or negative, which will affect the sort order.
1443 /// if f32::NAN.is_sign_negative() {
1444 /// assert!(bois.into_iter().map(|b| b.weight)
1445 /// .zip([f32::NAN, -5.0, 0.1, 10.0, 99.0, f32::INFINITY].iter())
1446 /// .all(|(a, b)| a.to_bits() == b.to_bits()))
1447 /// } else {
1448 /// assert!(bois.into_iter().map(|b| b.weight)
1449 /// .zip([-5.0, 0.1, 10.0, 99.0, f32::INFINITY, f32::NAN].iter())
1450 /// .all(|(a, b)| a.to_bits() == b.to_bits()))
1451 /// }
f9f354fc 1452 /// ```
04454e1e 1453 #[stable(feature = "total_cmp", since = "1.62.0")]
3c0e092e 1454 #[must_use]
f9f354fc
XL
1455 #[inline]
1456 pub fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering {
1457 let mut left = self.to_bits() as i32;
1458 let mut right = other.to_bits() as i32;
1459
1460 // In case of negatives, flip all the bits except the sign
1461 // to achieve a similar layout as two's complement integers
1462 //
1463 // Why does this work? IEEE 754 floats consist of three fields:
1464 // Sign bit, exponent and mantissa. The set of exponent and mantissa
1465 // fields as a whole have the property that their bitwise order is
1466 // equal to the numeric magnitude where the magnitude is defined.
1467 // The magnitude is not normally defined on NaN values, but
1468 // IEEE 754 totalOrder defines the NaN values also to follow the
1469 // bitwise order. This leads to order explained in the doc comment.
1470 // However, the representation of magnitude is the same for negative
1471 // and positive numbers – only the sign bit is different.
1472 // To easily compare the floats as signed integers, we need to
1473 // flip the exponent and mantissa bits in case of negative numbers.
1474 // We effectively convert the numbers to "two's complement" form.
1475 //
1476 // To do the flipping, we construct a mask and XOR against it.
1477 // We branchlessly calculate an "all-ones except for the sign bit"
1478 // mask from negative-signed values: right shifting sign-extends
1479 // the integer, so we "fill" the mask with sign bits, and then
1480 // convert to unsigned to push one more zero bit.
1481 // On positive values, the mask is all zeros, so it's a no-op.
1482 left ^= (((left >> 31) as u32) >> 1) as i32;
1483 right ^= (((right >> 31) as u32) >> 1) as i32;
1484
1485 left.cmp(&right)
1486 }
fc512014
XL
1487
1488 /// Restrict a value to a certain interval unless it is NaN.
1489 ///
1490 /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
1491 /// less than `min`. Otherwise this returns `self`.
1492 ///
1493 /// Note that this function returns NaN if the initial value was NaN as
1494 /// well.
1495 ///
1496 /// # Panics
1497 ///
1498 /// Panics if `min > max`, `min` is NaN, or `max` is NaN.
1499 ///
1500 /// # Examples
1501 ///
1502 /// ```
1503 /// assert!((-3.0f32).clamp(-2.0, 1.0) == -2.0);
1504 /// assert!((0.0f32).clamp(-2.0, 1.0) == 0.0);
1505 /// assert!((2.0f32).clamp(-2.0, 1.0) == 1.0);
1506 /// assert!((f32::NAN).clamp(-2.0, 1.0).is_nan());
1507 /// ```
1508 #[must_use = "method returns a new number and does not mutate the original value"]
1509 #[stable(feature = "clamp", since = "1.50.0")]
1510 #[inline]
f2b60f7d 1511 pub fn clamp(mut self, min: f32, max: f32) -> f32 {
353b0b11 1512 assert!(min <= max, "min > max, or either was NaN. min = {min:?}, max = {max:?}");
f2b60f7d
FG
1513 if self < min {
1514 self = min;
fc512014 1515 }
f2b60f7d
FG
1516 if self > max {
1517 self = max;
fc512014 1518 }
f2b60f7d 1519 self
fc512014 1520 }
83c7162d 1521}