diff options
| author | Simonas Kazlauskas <git@kazlauskas.me> | 2017-06-04 21:39:00 +0300 |
|---|---|---|
| committer | Simonas Kazlauskas <git@kazlauskas.me> | 2017-06-14 21:58:17 +0300 |
| commit | ba6cf1d80ac6f5ff3c36c7f6111197d429369d86 (patch) | |
| tree | a3b4c369f30cbd89510a69b7bf5b3fc7239cafba /src/libcore/num | |
| parent | 0da9721ab49d80bf74208e94a891b12c4a248507 (diff) | |
Re-implement float min/max in rust
See #42423
Diffstat (limited to 'src/libcore/num')
| -rw-r--r-- | src/libcore/num/f32.rs | 28 | ||||
| -rw-r--r-- | src/libcore/num/f64.rs | 28 | ||||
| -rw-r--r-- | src/libcore/num/mod.rs | 7 |
3 files changed, 63 insertions, 0 deletions
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 91ca213e96e..cb28035682d 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -242,4 +242,32 @@ impl Float for f32 { let value: f32 = consts::PI; self * (value / 180.0f32) } + + /// Returns the maximum of the two numbers. + #[inline] + fn max(self, other: f32) -> f32 { + // IEEE754 says: maxNum(x, y) is the canonicalized number y if x < y, x if y < x, the + // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it + // is either x or y, canonicalized (this means results might differ among implementations). + // When either x or y is a signalingNaN, then the result is according to 6.2. + // + // Since we do not support sNaN in Rust yet, we do not need to handle them. + // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by + // multiplying by 1.0. Should switch to the `canonicalize` when it works. + (if self < other || self.is_nan() { other } else { self }) * 1.0 + } + + /// Returns the minimum of the two numbers. + #[inline] + fn min(self, other: f32) -> f32 { + // IEEE754 says: minNum(x, y) is the canonicalized number x if x < y, y if y < x, the + // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it + // is either x or y, canonicalized (this means results might differ among implementations). + // When either x or y is a signalingNaN, then the result is according to 6.2. + // + // Since we do not support sNaN in Rust yet, we do not need to handle them. + // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by + // multiplying by 1.0. Should switch to the `canonicalize` when it works. + (if self < other || other.is_nan() { self } else { other }) * 1.0 + } } diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 7d6d6cef049..ac6b1e67cd2 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -242,4 +242,32 @@ impl Float for f64 { let value: f64 = consts::PI; self * (value / 180.0) } + + /// Returns the maximum of the two numbers. + #[inline] + fn max(self, other: f64) -> f64 { + // IEEE754 says: maxNum(x, y) is the canonicalized number y if x < y, x if y < x, the + // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it + // is either x or y, canonicalized (this means results might differ among implementations). + // When either x or y is a signalingNaN, then the result is according to 6.2. + // + // Since we do not support sNaN in Rust yet, we do not need to handle them. + // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by + // multiplying by 1.0. Should switch to the `canonicalize` when it works. + (if self < other || self.is_nan() { other } else { self }) * 1.0 + } + + /// Returns the minimum of the two numbers. + #[inline] + fn min(self, other: f64) -> f64 { + // IEEE754 says: minNum(x, y) is the canonicalized number x if x < y, y if y < x, the + // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it + // is either x or y, canonicalized (this means results might differ among implementations). + // When either x or y is a signalingNaN, then the result is according to 6.2. + // + // Since we do not support sNaN in Rust yet, we do not need to handle them. + // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by + // multiplying by 1.0. Should switch to the `canonicalize` when it works. + (if self < other || other.is_nan() { self } else { other }) * 1.0 + } } diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index be093cca6a1..b252d50b02a 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -2428,6 +2428,13 @@ pub trait Float: Sized { /// Convert degrees to radians. #[stable(feature = "deg_rad_conversions", since="1.7.0")] fn to_radians(self) -> Self; + + /// Returns the maximum of the two numbers. + #[stable(feature = "core_float_min_max", since="1.20.0")] + fn max(self, other: Self) -> Self; + /// Returns the minimum of the two numbers. + #[stable(feature = "core_float_min_max", since="1.20.0")] + fn min(self, other: Self) -> Self; } macro_rules! from_str_radix_int_impl { |
