diff options
| author | Simonas Kazlauskas <git@kazlauskas.me> | 2017-06-04 21:44:57 +0300 |
|---|---|---|
| committer | Simonas Kazlauskas <git@kazlauskas.me> | 2017-06-22 23:12:01 +0300 |
| commit | 3b9fe77bfcd4c800fab8afcdcc82d31facdc515b (patch) | |
| tree | 464db7167313be8d61001eabd038521e9fcf0d0e /src/libcore | |
| parent | 0da9721ab49d80bf74208e94a891b12c4a248507 (diff) | |
| download | rust-3b9fe77bfcd4c800fab8afcdcc82d31facdc515b.tar.gz rust-3b9fe77bfcd4c800fab8afcdcc82d31facdc515b.zip | |
Fix NaN handling in is_sign_negative/positive
See #42425
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/num/f32.rs | 19 | ||||
| -rw-r--r-- | src/libcore/num/f64.rs | 17 |
2 files changed, 24 insertions, 12 deletions
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 91ca213e96e..aca37221f09 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -205,18 +205,25 @@ impl Float for f32 { } } - /// Returns `true` if `self` is positive, including `+0.0` and - /// `Float::infinity()`. + /// Returns `true` if and only if `self` has a positive sign, including `+0.0`, `NaN`s with + /// positive sign bit and positive infinity. #[inline] fn is_sign_positive(self) -> bool { - self > 0.0 || (1.0 / self) == INFINITY + !self.is_sign_negative() } - /// Returns `true` if `self` is negative, including `-0.0` and - /// `Float::neg_infinity()`. + /// Returns `true` if and only if `self` has a negative sign, including `-0.0`, `NaN`s with + /// negative sign bit and negative infinity. #[inline] fn is_sign_negative(self) -> bool { - self < 0.0 || (1.0 / self) == NEG_INFINITY + // IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus + // applies to zeros and NaNs as well. + #[repr(C)] + union F32Bytes { + f: f32, + b: u32 + } + unsafe { F32Bytes { f: self }.b & 0x8000_0000 != 0 } } /// Returns the reciprocal (multiplicative inverse) of the number. diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 7d6d6cef049..ebe5daa67a7 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -205,18 +205,23 @@ impl Float for f64 { } } - /// Returns `true` if `self` is positive, including `+0.0` and - /// `Float::infinity()`. + /// Returns `true` if and only if `self` has a positive sign, including `+0.0`, `NaN`s with + /// positive sign bit and positive infinity. #[inline] fn is_sign_positive(self) -> bool { - self > 0.0 || (1.0 / self) == INFINITY + !self.is_sign_negative() } - /// Returns `true` if `self` is negative, including `-0.0` and - /// `Float::neg_infinity()`. + /// Returns `true` if and only if `self` has a negative sign, including `-0.0`, `NaN`s with + /// negative sign bit and negative infinity. #[inline] fn is_sign_negative(self) -> bool { - self < 0.0 || (1.0 / self) == NEG_INFINITY + #[repr(C)] + union F64Bytes { + f: f64, + b: u64 + } + unsafe { F64Bytes { f: self }.b & 0x8000_0000_0000_0000 != 0 } } /// Returns the reciprocal (multiplicative inverse) of the number. |
