summary refs log tree commit diff
path: root/src/libcore/num
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-06-16 17:52:11 +0000
committerbors <bors@rust-lang.org>2017-06-16 17:52:11 +0000
commitfe7227f6c8704f0186091085a14fd1027920e4bb (patch)
tree8c3cb396146179783cb6d001fa7f4f67c6958575 /src/libcore/num
parentb40be00a0cac84d23f51c5c5109c8f824ab19ab3 (diff)
parentba6cf1d80ac6f5ff3c36c7f6111197d429369d86 (diff)
downloadrust-fe7227f6c8704f0186091085a14fd1027920e4bb.tar.gz
rust-fe7227f6c8704f0186091085a14fd1027920e4bb.zip
Auto merge of #42430 - nagisa:core-float, r=alexcrichton
Re-implement float min/max in rust

This also adds the relevant implementations into libcore.

See #42423
Diffstat (limited to 'src/libcore/num')
-rw-r--r--src/libcore/num/f32.rs28
-rw-r--r--src/libcore/num/f64.rs28
-rw-r--r--src/libcore/num/mod.rs7
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 62d75445cc9..cbd59ed3713 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -2459,6 +2459,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 {