about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorFabian Zaiser <fabian.zaiser@gmail.com>2018-03-26 20:15:19 +0200
committerFabian Zaiser <fabian.zaiser@gmail.com>2018-03-26 20:25:42 +0200
commit9255bbd035ee032f1ccd47fcf93c87f7bc2e4bad (patch)
treef0eafd65463def219f58c69a440fa034913ea798 /src/libstd
parent13a86f4d8555702085b97de3a42234a82ddc045d (diff)
downloadrust-9255bbd035ee032f1ccd47fcf93c87f7bc2e4bad.tar.gz
rust-9255bbd035ee032f1ccd47fcf93c87f7bc2e4bad.zip
Implement RFC #2169 (Euclidean division).
Tracking issue: #49048
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/f32.rs51
-rw-r--r--src/libstd/f64.rs50
2 files changed, 101 insertions, 0 deletions
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index ceb019bc95b..ed63f445084 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -329,6 +329,57 @@ impl f32 {
         unsafe { intrinsics::fmaf32(self, a, b) }
     }
 
+    /// Calculates Euclidean division, the matching method for `mod_euc`.
+    ///
+    /// This computes the integer n such that
+    /// `self = n * rhs + self.mod_euc(rhs)`.
+    /// In other words, the result is `self / rhs` rounded to the integer n
+    /// such that `self >= n * rhs`.
+    ///
+    /// ```
+    /// #![feature(euclidean_division)]
+    /// let a: f32 = 7.0;
+    /// let b = 4.0;
+    /// assert_eq!(a.div_euc(b), 1.0); // 7.0 > 4.0 * 1.0
+    /// assert_eq!((-a).div_euc(b), -2.0); // -7.0 >= 4.0 * -2.0
+    /// assert_eq!(a.div_euc(-b), -1.0); // 7.0 >= -4.0 * -1.0
+    /// assert_eq!((-a).div_euc(-b), 2.0); // -7.0 >= -4.0 * 2.0
+    /// ```
+    #[inline]
+    #[unstable(feature = "euclidean_division", issue = "49048")]
+    pub fn div_euc(self, rhs: f32) -> f32 {
+        let q = (self / rhs).trunc();
+        if self % rhs < 0.0 {
+            return if rhs > 0.0 { q - 1.0 } else { q + 1.0 }
+        }
+        q
+    }
+
+    /// Calculates the Euclidean modulo (self mod rhs), which is never negative.
+    ///
+    /// In particular, the result `n` satisfies `0 <= n < rhs.abs()`.
+    ///
+    /// ```
+    /// #![feature(euclidean_division)]
+    /// let a: f32 = 7.0;
+    /// let b = 4.0;
+    /// assert_eq!(a.mod_euc(b), 3.0);
+    /// assert_eq!((-a).mod_euc(b), 1.0);
+    /// assert_eq!(a.mod_euc(-b), 3.0);
+    /// assert_eq!((-a).mod_euc(-b), 1.0);
+    /// ```
+    #[inline]
+    #[unstable(feature = "euclidean_division", issue = "49048")]
+    pub fn mod_euc(self, rhs: f32) -> f32 {
+        let r = self % rhs;
+        if r < 0.0 {
+            r + rhs.abs()
+        } else {
+            r
+        }
+    }
+
+
     /// Takes the reciprocal (inverse) of a number, `1/x`.
     ///
     /// ```
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index 97adf108b73..320655c443c 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -315,6 +315,56 @@ impl f64 {
         unsafe { intrinsics::fmaf64(self, a, b) }
     }
 
+    /// Calculates Euclidean division, the matching method for `mod_euc`.
+    ///
+    /// This computes the integer n such that
+    /// `self = n * rhs + self.mod_euc(rhs)`.
+    /// In other words, the result is `self / rhs` rounded to the integer n
+    /// such that `self >= n * rhs`.
+    ///
+    /// ```
+    /// #![feature(euclidean_division)]
+    /// let a: f64 = 7.0;
+    /// let b = 4.0;
+    /// assert_eq!(a.div_euc(b), 1.0); // 7.0 > 4.0 * 1.0
+    /// assert_eq!((-a).div_euc(b), -2.0); // -7.0 >= 4.0 * -2.0
+    /// assert_eq!(a.div_euc(-b), -1.0); // 7.0 >= -4.0 * -1.0
+    /// assert_eq!((-a).div_euc(-b), 2.0); // -7.0 >= -4.0 * 2.0
+    /// ```
+    #[inline]
+    #[unstable(feature = "euclidean_division", issue = "49048")]
+    pub fn div_euc(self, rhs: f64) -> f64 {
+        let q = (self / rhs).trunc();
+        if self % rhs < 0.0 {
+            return if rhs > 0.0 { q - 1.0 } else { q + 1.0 }
+        }
+        q
+    }
+
+    /// Calculates the Euclidean modulo (self mod rhs), which is never negative.
+    ///
+    /// In particular, the result `n` satisfies `0 <= n < rhs.abs()`.
+    ///
+    /// ```
+    /// #![feature(euclidean_division)]
+    /// let a: f64 = 7.0;
+    /// let b = 4.0;
+    /// assert_eq!(a.mod_euc(b), 3.0);
+    /// assert_eq!((-a).mod_euc(b), 1.0);
+    /// assert_eq!(a.mod_euc(-b), 3.0);
+    /// assert_eq!((-a).mod_euc(-b), 1.0);
+    /// ```
+    #[inline]
+    #[unstable(feature = "euclidean_division", issue = "49048")]
+    pub fn mod_euc(self, rhs: f64) -> f64 {
+        let r = self % rhs;
+        if r < 0.0 {
+            r + rhs.abs()
+        } else {
+            r
+        }
+    }
+
     /// Takes the reciprocal (inverse) of a number, `1/x`.
     ///
     /// ```