diff options
| author | bors <bors@rust-lang.org> | 2018-04-13 07:34:37 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-04-13 07:34:37 +0000 |
| commit | f9f9050f507cd14839f868917b5b4fc370eed54b (patch) | |
| tree | f3f87ea503aad52e3cb90da78c09ef5d8abdbcfe /src/libstd | |
| parent | eec3208c4cee937356199b30e0419357777c5070 (diff) | |
| parent | ca4e458089d0fecb8684de0437534d5f40b003bf (diff) | |
| download | rust-f9f9050f507cd14839f868917b5b4fc370eed54b.tar.gz rust-f9f9050f507cd14839f868917b5b4fc370eed54b.zip | |
Auto merge of #49389 - fanzier:euclidean-division, r=KodrAus
Implement RFC #2169 (Euclidean modulo). Tracking issue: #49048
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/f32.rs | 51 | ||||
| -rw-r--r-- | src/libstd/f64.rs | 50 |
2 files changed, 101 insertions, 0 deletions
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index ceb019bc95b..ca39089a958 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..a9585670ad0 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`. /// /// ``` |
