| 
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`](#method.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