|  | 
| 11 | 11 | 
 | 
| 12 | 12 | #![unstable(feature = "f128", issue = "116909")] | 
| 13 | 13 | 
 | 
|  | 14 | +use crate::mem; | 
|  | 15 | + | 
| 14 | 16 | /// Basic mathematical constants. | 
| 15 | 17 | #[unstable(feature = "f128", issue = "116909")] | 
| 16 | 18 | pub mod consts {} | 
|  | 19 | + | 
|  | 20 | +#[cfg(not(test))] | 
|  | 21 | +impl f128 { | 
|  | 22 | +    // FIXME(f16_f128): almost everything in this `impl` is missing examples and a const | 
|  | 23 | +    // implementation. Add these once we can run code on all platforms and have f16/f128 in CTFE. | 
|  | 24 | + | 
|  | 25 | +    /// Returns `true` if this value is NaN. | 
|  | 26 | +    #[inline] | 
|  | 27 | +    #[must_use] | 
|  | 28 | +    #[unstable(feature = "f128", issue = "116909")] | 
|  | 29 | +    #[allow(clippy::eq_op)] // > if you intended to check if the operand is NaN, use `.is_nan()` instead :) | 
|  | 30 | +    pub const fn is_nan(self) -> bool { | 
|  | 31 | +        self != self | 
|  | 32 | +    } | 
|  | 33 | + | 
|  | 34 | +    /// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with | 
|  | 35 | +    /// positive sign bit and positive infinity. Note that IEEE 754 doesn't assign any | 
|  | 36 | +    /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that | 
|  | 37 | +    /// the bit pattern of NaNs are conserved over arithmetic operations, the result of | 
|  | 38 | +    /// `is_sign_positive` on a NaN might produce an unexpected result in some cases. | 
|  | 39 | +    /// See [explanation of NaN as a special value](f32) for more info. | 
|  | 40 | +    #[inline] | 
|  | 41 | +    #[must_use] | 
|  | 42 | +    #[unstable(feature = "f128", issue = "116909")] | 
|  | 43 | +    pub fn is_sign_positive(self) -> bool { | 
|  | 44 | +        !self.is_sign_negative() | 
|  | 45 | +    } | 
|  | 46 | + | 
|  | 47 | +    /// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with | 
|  | 48 | +    /// negative sign bit and negative infinity. Note that IEEE 754 doesn't assign any | 
|  | 49 | +    /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that | 
|  | 50 | +    /// the bit pattern of NaNs are conserved over arithmetic operations, the result of | 
|  | 51 | +    /// `is_sign_negative` on a NaN might produce an unexpected result in some cases. | 
|  | 52 | +    /// See [explanation of NaN as a special value](f32) for more info. | 
|  | 53 | +    #[inline] | 
|  | 54 | +    #[must_use] | 
|  | 55 | +    #[unstable(feature = "f128", issue = "116909")] | 
|  | 56 | +    pub fn is_sign_negative(self) -> bool { | 
|  | 57 | +        // IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus | 
|  | 58 | +        // applies to zeros and NaNs as well. | 
|  | 59 | +        // SAFETY: This is just transmuting to get the sign bit, it's fine. | 
|  | 60 | +        (self.to_bits() & (1 << 127)) != 0 | 
|  | 61 | +    } | 
|  | 62 | + | 
|  | 63 | +    /// Raw transmutation to `u128`. | 
|  | 64 | +    /// | 
|  | 65 | +    /// This is currently identical to `transmute::<f128, u128>(self)` on all platforms. | 
|  | 66 | +    /// | 
|  | 67 | +    /// See [`from_bits`](Self::from_bits) for some discussion of the | 
|  | 68 | +    /// portability of this operation (there are almost no issues). | 
|  | 69 | +    /// | 
|  | 70 | +    /// Note that this function is distinct from `as` casting, which attempts to | 
|  | 71 | +    /// preserve the *numeric* value, and not the bitwise value. | 
|  | 72 | +    #[inline] | 
|  | 73 | +    #[unstable(feature = "f128", issue = "116909")] | 
|  | 74 | +    #[must_use = "this returns the result of the operation, without modifying the original"] | 
|  | 75 | +    pub fn to_bits(self) -> u128 { | 
|  | 76 | +        // SAFETY: `u128` is a plain old datatype so we can always... uh... | 
|  | 77 | +        // ...look, just pretend you forgot what you just read. | 
|  | 78 | +        // Stability concerns. | 
|  | 79 | +        unsafe { mem::transmute(self) } | 
|  | 80 | +    } | 
|  | 81 | + | 
|  | 82 | +    /// Raw transmutation from `u128`. | 
|  | 83 | +    /// | 
|  | 84 | +    /// This is currently identical to `transmute::<u128, f128>(v)` on all platforms. | 
|  | 85 | +    /// It turns out this is incredibly portable, for two reasons: | 
|  | 86 | +    /// | 
|  | 87 | +    /// * Floats and Ints have the same endianness on all supported platforms. | 
|  | 88 | +    /// * IEEE 754 very precisely specifies the bit layout of floats. | 
|  | 89 | +    /// | 
|  | 90 | +    /// However there is one caveat: prior to the 2008 version of IEEE 754, how | 
|  | 91 | +    /// to interpret the NaN signaling bit wasn't actually specified. Most platforms | 
|  | 92 | +    /// (notably x86 and ARM) picked the interpretation that was ultimately | 
|  | 93 | +    /// standardized in 2008, but some didn't (notably MIPS). As a result, all | 
|  | 94 | +    /// signaling NaNs on MIPS are quiet NaNs on x86, and vice-versa. | 
|  | 95 | +    /// | 
|  | 96 | +    /// Rather than trying to preserve signaling-ness cross-platform, this | 
|  | 97 | +    /// implementation favors preserving the exact bits. This means that | 
|  | 98 | +    /// any payloads encoded in NaNs will be preserved even if the result of | 
|  | 99 | +    /// this method is sent over the network from an x86 machine to a MIPS one. | 
|  | 100 | +    /// | 
|  | 101 | +    /// If the results of this method are only manipulated by the same | 
|  | 102 | +    /// architecture that produced them, then there is no portability concern. | 
|  | 103 | +    /// | 
|  | 104 | +    /// If the input isn't NaN, then there is no portability concern. | 
|  | 105 | +    /// | 
|  | 106 | +    /// If you don't care about signalingness (very likely), then there is no | 
|  | 107 | +    /// portability concern. | 
|  | 108 | +    /// | 
|  | 109 | +    /// Note that this function is distinct from `as` casting, which attempts to | 
|  | 110 | +    /// preserve the *numeric* value, and not the bitwise value. | 
|  | 111 | +    #[inline] | 
|  | 112 | +    #[must_use] | 
|  | 113 | +    #[unstable(feature = "f128", issue = "116909")] | 
|  | 114 | +    pub fn from_bits(v: u128) -> Self { | 
|  | 115 | +        // SAFETY: `u128 is a plain old datatype so we can always... uh... | 
|  | 116 | +        // ...look, just pretend you forgot what you just read. | 
|  | 117 | +        // Stability concerns. | 
|  | 118 | +        unsafe { mem::transmute(v) } | 
|  | 119 | +    } | 
|  | 120 | +} | 
0 commit comments