From 9255bbd035ee032f1ccd47fcf93c87f7bc2e4bad Mon Sep 17 00:00:00 2001 From: Fabian Zaiser Date: Mon, 26 Mar 2018 20:15:19 +0200 Subject: [PATCH 1/5] Implement RFC #2169 (Euclidean division). Tracking issue: #49048 --- src/libcore/num/mod.rs | 436 +++++++++++++++++++++++++++++++++++++++++ src/libstd/f32.rs | 51 +++++ src/libstd/f64.rs | 50 +++++ 3 files changed, 537 insertions(+) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 18e0aa453d8df..b4a43b216e833 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -633,6 +633,32 @@ $EndFeature, " } } + doc_comment! { + concat!("Checked Euclidean division. Computes `self.div_euc(rhs)`, returning `None` if `rhs == 0` +or the division results in overflow. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!((", stringify!($SelfT), +"::min_value() + 1).checked_div_euc(-1), Some(", stringify!($Max), ")); +assert_eq!(", stringify!($SelfT), "::min_value().checked_div_euc(-1), None); +assert_eq!((1", stringify!($SelfT), ").checked_div_euc(0), None);", +$EndFeature, " +```"), + #[unstable(feature = "euclidean_division", issue = "49048")] + #[inline] + pub fn checked_div_euc(self, rhs: Self) -> Option { + if rhs == 0 || (self == Self::min_value() && rhs == -1) { + None + } else { + Some(self.div_euc(rhs)) + } + } + } + doc_comment! { concat!("Checked integer remainder. Computes `self % rhs`, returning `None` if `rhs == 0` or the division results in overflow. @@ -660,6 +686,33 @@ $EndFeature, " } } + doc_comment! { + concat!("Checked Euclidean modulo. Computes `self.mod_euc(rhs)`, returning `None` if +`rhs == 0` or the division results in overflow. + +# Examples + +Basic usage: + +``` +", $Feature, "use std::", stringify!($SelfT), "; + +assert_eq!(5", stringify!($SelfT), ".checked_mod_euc(2), Some(1)); +assert_eq!(5", stringify!($SelfT), ".checked_mod_euc(0), None); +assert_eq!(", stringify!($SelfT), "::MIN.checked_mod_euc(-1), None);", +$EndFeature, " +```"), + #[unstable(feature = "euclidean_division", issue = "49048")] + #[inline] + pub fn checked_mod_euc(self, rhs: Self) -> Option { + if rhs == 0 || (self == Self::min_value() && rhs == -1) { + None + } else { + Some(self.mod_euc(rhs)) + } + } + } + doc_comment! { concat!("Checked negation. Computes `-self`, returning `None` if `self == MIN`. @@ -993,6 +1046,34 @@ $EndFeature, " } } + doc_comment! { + concat!("Wrapping Euclidean division. Computes `self.div_euc(rhs)`, wrapping around at the +boundary of the type. + +The only case where such wrapping can occur is when one divides `MIN / -1` on a signed type (where +`MIN` is the negative minimal value for the type); this is equivalent to `-MIN`, a positive value +that is too large to represent in the type. In such a case, this function returns `MIN` itself. + +# Panics + +This function will panic if `rhs` is 0. + +# Examples + +Basic usage: + +``` +assert_eq!(100", stringify!($SelfT), ".wrapping_div_euc(10), 10); +assert_eq!((-128i8).wrapping_div_euc(-1), -128);", +$EndFeature, " +```"), + #[unstable(feature = "euclidean_division", issue = "49048")] + #[inline] + pub fn wrapping_div_euc(self, rhs: Self) -> Self { + self.overflowing_div_euc(rhs).0 + } + } + doc_comment! { concat!("Wrapping (modular) remainder. Computes `self % rhs`, wrapping around at the boundary of the type. @@ -1021,6 +1102,34 @@ $EndFeature, " } } + doc_comment! { + concat!("Wrapping Euclidean modulo. Computes `self.mod_euc(rhs)`, wrapping around at the +boundary of the type. + +Such wrap-around never actually occurs mathematically; implementation artifacts make `x % y` +invalid for `MIN / -1` on a signed type (where `MIN` is the negative minimal value). In such a case, +this function returns `0`. + +# Panics + +This function will panic if `rhs` is 0. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_mod_euc(10), 0); +assert_eq!((-128i8).wrapping_mod_euc(-1), 0);", +$EndFeature, " +```"), + #[unstable(feature = "euclidean_division", issue = "49048")] + #[inline] + pub fn wrapping_mod_euc(self, rhs: Self) -> Self { + self.overflowing_mod_euc(rhs).0 + } + } + doc_comment! { concat!("Wrapping (modular) negation. Computes `-self`, wrapping around at the boundary of the type. @@ -1286,6 +1395,39 @@ $EndFeature, " } } + doc_comment! { + concat!("Calculates the quotient of Euclidean division `self.div_euc(rhs)`. + +Returns a tuple of the divisor along with a boolean indicating whether an arithmetic overflow would +occur. If an overflow would occur then self is returned. + +# Panics + +This function will panic if `rhs` is 0. + +# Examples + +Basic usage: + +``` +", $Feature, "use std::", stringify!($SelfT), "; + +assert_eq!(5", stringify!($SelfT), ".overflowing_div_euc(2), (2, false)); +assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div_euc(-1), (", stringify!($SelfT), +"::MIN, true));", +$EndFeature, " +```"), + #[inline] + #[unstable(feature = "euclidean_division", issue = "49048")] + pub fn overflowing_div_euc(self, rhs: Self) -> (Self, bool) { + if self == Self::min_value() && rhs == -1 { + (self, true) + } else { + (self.div_euc(rhs), false) + } + } + } + doc_comment! { concat!("Calculates the remainder when `self` is divided by `rhs`. @@ -1318,6 +1460,40 @@ $EndFeature, " } } + + doc_comment! { + concat!("Calculates the modulo of Euclidean divsion `self.mod_euc(rhs)`. + +Returns a tuple of the remainder after dividing along with a boolean indicating whether an +arithmetic overflow would occur. If an overflow would occur then 0 is returned. + +# Panics + +This function will panic if `rhs` is 0. + +# Examples + +Basic usage: + +``` +", $Feature, "use std::", stringify!($SelfT), "; + +assert_eq!(5", stringify!($SelfT), ".overflowing_mod_euc(2), (1, false)); +assert_eq!(", stringify!($SelfT), "::MIN.overflowing_mod_euc(-1), (0, true));", +$EndFeature, " +```"), + #[unstable(feature = "euclidean_division", issue = "49048")] + #[inline] + pub fn overflowing_mod_euc(self, rhs: Self) -> (Self, bool) { + if self == Self::min_value() && rhs == -1 { + (0, true) + } else { + (self.mod_euc(rhs), false) + } + } + } + + doc_comment! { concat!("Negates self, overflowing if this is equal to the minimum value. @@ -1512,6 +1688,80 @@ $EndFeature, " } } + doc_comment! { + concat!("Calculates the quotient of Euclidean division of `self` by `rhs`. + +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`. + +# Panics + +This function will panic if `rhs` is 0. + +# Examples + +Basic usage: + +``` +", $Feature, "let a: ", stringify!($SelfT), " = 7; // or any other integer type +let b = 4; + +assert_eq!(a.div_euc(b), 1); // 7 >= 4 * 1 +assert_eq!(a.div_euc(-b), -1); // 7 >= -4 * -1 +assert_eq!((-a).div_euc(b), -2); // -7 >= 4 * -2 +assert_eq!((-a).div_euc(-b), 2); // -7 >= -4 * 2", +$EndFeature, " +```"), + #[unstable(feature = "euclidean_division", issue = "49048")] + #[inline] + #[rustc_inherit_overflow_checks] + pub fn div_euc(self, rhs: Self) -> Self { + let q = self / rhs; + if self % rhs < 0 { + return if rhs > 0 { q - 1 } else { q + 1 } + } + q + } + } + + + doc_comment! { + concat!("Calculates the modulo `self mod rhs` by Euclidean division. + +In particular, the result `n` satisfies `0 <= n < rhs.abs()`. + +# Panics + +This function will panic if `rhs` is 0. + +# Examples + +Basic usage: + +``` +", $Feature, "let a: ", stringify!($SelfT), " = 7; // or any other integer type +let b = 4; + +assert_eq!(a.mod_euc(b), 3); +assert_eq!((-a).mod_euc(b), 1); +assert_eq!(a.mod_euc(-b), 3); +assert_eq!((-a).mod_euc(-b), 1);", +$EndFeature, " +```"), + #[unstable(feature = "euclidean_division", issue = "49048")] + #[inline] + #[rustc_inherit_overflow_checks] + pub fn mod_euc(self, rhs: Self) -> Self { + let r = self % rhs; + if r < 0 { + r + rhs.abs() + } else { + r + } + } + } + doc_comment! { concat!("Computes the absolute value of `self`. @@ -2103,6 +2353,30 @@ assert_eq!(1", stringify!($SelfT), ".checked_div(0), None);", $EndFeature, " } } + doc_comment! { + concat!("Checked Euclidean division. Computes `self.div_euc(rhs)`, returning `None` +if `rhs == 0`. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(128", stringify!($SelfT), ".checked_div(2), Some(64)); +assert_eq!(1", stringify!($SelfT), ".checked_div_euc(0), None); +```"), + #[unstable(feature = "euclidean_division", issue = "49048")] + #[inline] + pub fn checked_div_euc(self, rhs: Self) -> Option { + if rhs == 0 { + None + } else { + Some(self.div_euc(rhs)) + } + } + } + + doc_comment! { concat!("Checked integer remainder. Computes `self % rhs`, returning `None` if `rhs == 0`. @@ -2126,6 +2400,30 @@ assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);", $EndFeature, " } } + doc_comment! { + concat!("Checked Euclidean modulo. Computes `self.mod_euc(rhs)`, returning `None` +if `rhs == 0`. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(5", stringify!($SelfT), ".checked_mod_euc(2), Some(1)); +assert_eq!(5", stringify!($SelfT), ".checked_mod_euc(0), None);", +$EndFeature, " +```"), + #[unstable(feature = "euclidean_division", issue = "49048")] + #[inline] + pub fn checked_mod_euc(self, rhs: Self) -> Option { + if rhs == 0 { + None + } else { + Some(self.mod_euc(rhs)) + } + } + } + doc_comment! { concat!("Checked negation. Computes `-self`, returning `None` unless `self == 0`. @@ -2405,6 +2703,27 @@ Basic usage: } } + doc_comment! { + concat!("Wrapping Euclidean division. Computes `self.div_euc(rhs)`. +Wrapped division on unsigned types is just normal division. +There's no way wrapping could ever happen. +This function exists, so that all operations +are accounted for in the wrapping operations. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_div_euc(10), 10);", $EndFeature, " +```"), + #[unstable(feature = "euclidean_division", issue = "49048")] + #[inline] + pub fn wrapping_div_euc(self, rhs: Self) -> Self { + self.div_euc(rhs) + } + } + doc_comment! { concat!("Wrapping (modular) remainder. Computes `self % rhs`. Wrapped remainder calculation on unsigned types is @@ -2427,6 +2746,28 @@ Basic usage: } } + doc_comment! { + concat!("Wrapping Euclidean modulo. Computes `self.mod_euc(rhs)`. +Wrapped modulo calculation on unsigned types is +just the regular remainder calculation. +There's no way wrapping could ever happen. +This function exists, so that all operations +are accounted for in the wrapping operations. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_mod_euc(10), 0);", $EndFeature, " +```"), + #[unstable(feature = "euclidean_division", issue = "49048")] + #[inline] + pub fn wrapping_mod_euc(self, rhs: Self) -> Self { + self % rhs + } + } + /// Wrapping (modular) negation. Computes `-self`, /// wrapping around at the boundary of the type. /// @@ -2660,6 +3001,32 @@ Basic usage } } + doc_comment! { + concat!("Calculates the quotient of Euclidean division `self.div_euc(rhs)`. + +Returns a tuple of the divisor along with a boolean indicating +whether an arithmetic overflow would occur. Note that for unsigned +integers overflow never occurs, so the second value is always +`false`. + +# Panics + +This function will panic if `rhs` is 0. + +# Examples + +Basic usage + +``` +", $Feature, "assert_eq!(5", stringify!($SelfT), ".overflowing_div_euc(2), (2, false));", $EndFeature, " +```"), + #[inline] + #[unstable(feature = "euclidean_division", issue = "49048")] + pub fn overflowing_div_euc(self, rhs: Self) -> (Self, bool) { + (self / rhs, false) + } + } + doc_comment! { concat!("Calculates the remainder when `self` is divided by `rhs`. @@ -2686,6 +3053,32 @@ Basic usage } } + doc_comment! { + concat!("Calculates the modulo of Euclidean division of `self.mod_euc(rhs)`. + +Returns a tuple of the modulo after dividing along with a boolean +indicating whether an arithmetic overflow would occur. Note that for +unsigned integers overflow never occurs, so the second value is +always `false`. + +# Panics + +This function will panic if `rhs` is 0. + +# Examples + +Basic usage + +``` +", $Feature, "assert_eq!(5", stringify!($SelfT), ".overflowing_mod_euc(2), (1, false));", $EndFeature, " +```"), + #[inline] + #[unstable(feature = "euclidean_division", issue = "49048")] + pub fn overflowing_mod_euc(self, rhs: Self) -> (Self, bool) { + (self % rhs, false) + } + } + doc_comment! { concat!("Negates self in an overflowing fashion. @@ -2843,6 +3236,49 @@ Basic usage: } } + doc_comment! { + concat!("Performs Euclidean division. + +For unsigned types, this is just the same as `self / rhs`. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq(7", stringify!($SelfT), ".div_euc(4), 1); // or any other integer type", +$EndFeature, " +```"), + #[unstable(feature = "euclidean_division", issue = "49048")] + #[inline] + #[rustc_inherit_overflow_checks] + pub fn div_euc(self, rhs: Self) -> Self { + self / rhs + } + } + + + doc_comment! { + concat!("Calculates the Euclidean modulo `self mod rhs`. + +For unsigned types, this is just the same as `self % rhs`. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq(7", stringify!($SelfT), ".mod_euc(4), 3); // or any other integer type", +$EndFeature, " +```"), + #[unstable(feature = "euclidean_division", issue = "49048")] + #[inline] + #[rustc_inherit_overflow_checks] + pub fn mod_euc(self, rhs: Self) -> Self { + self % rhs + } + } + doc_comment! { concat!("Returns `true` if and only if `self == 2^k` for some `k`. diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index ceb019bc95b4c..ed63f44508462 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 97adf108b73b0..320655c443c6a 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`. /// /// ``` From ece87c3f4e76fd996dbbbaf8202f2adecff06c1e Mon Sep 17 00:00:00 2001 From: Fabian Zaiser Date: Wed, 28 Mar 2018 01:41:40 +0200 Subject: [PATCH 2/5] Address nits and tidy errors. --- src/libcore/num/mod.rs | 28 +++++++++++++++------------- src/libstd/f32.rs | 4 ++-- src/libstd/f64.rs | 4 ++-- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index b4a43b216e833..9e7e935715952 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -634,8 +634,8 @@ $EndFeature, " } doc_comment! { - concat!("Checked Euclidean division. Computes `self.div_euc(rhs)`, returning `None` if `rhs == 0` -or the division results in overflow. + concat!("Checked Euclidean division. Computes `self.div_euc(rhs)`, +returning `None` if `rhs == 0` or the division results in overflow. # Examples @@ -1047,8 +1047,8 @@ $EndFeature, " } doc_comment! { - concat!("Wrapping Euclidean division. Computes `self.div_euc(rhs)`, wrapping around at the -boundary of the type. + concat!("Wrapping Euclidean division. Computes `self.div_euc(rhs)`, +wrapping around at the boundary of the type. The only case where such wrapping can occur is when one divides `MIN / -1` on a signed type (where `MIN` is the negative minimal value for the type); this is equivalent to `-MIN`, a positive value @@ -1462,7 +1462,7 @@ $EndFeature, " doc_comment! { - concat!("Calculates the modulo of Euclidean divsion `self.mod_euc(rhs)`. + concat!("Calculates the remainder `self.mod_euc(rhs)` by Euclidean division. Returns a tuple of the remainder after dividing along with a boolean indicating whether an arithmetic overflow would occur. If an overflow would occur then 0 is returned. @@ -1691,8 +1691,8 @@ $EndFeature, " doc_comment! { concat!("Calculates the quotient of Euclidean division of `self` by `rhs`. -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 +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`. # Panics @@ -1727,7 +1727,7 @@ $EndFeature, " doc_comment! { - concat!("Calculates the modulo `self mod rhs` by Euclidean division. + concat!("Calculates the remainder `self mod rhs` by Euclidean division. In particular, the result `n` satisfies `0 <= n < rhs.abs()`. @@ -2720,7 +2720,7 @@ Basic usage: #[unstable(feature = "euclidean_division", issue = "49048")] #[inline] pub fn wrapping_div_euc(self, rhs: Self) -> Self { - self.div_euc(rhs) + self / rhs } } @@ -3018,7 +3018,8 @@ This function will panic if `rhs` is 0. Basic usage ``` -", $Feature, "assert_eq!(5", stringify!($SelfT), ".overflowing_div_euc(2), (2, false));", $EndFeature, " +", $Feature, "assert_eq!(5", stringify!($SelfT), ".overflowing_div_euc(2), (2, false));", +$EndFeature, " ```"), #[inline] #[unstable(feature = "euclidean_division", issue = "49048")] @@ -3054,7 +3055,7 @@ Basic usage } doc_comment! { - concat!("Calculates the modulo of Euclidean division of `self.mod_euc(rhs)`. + concat!("Calculates the remainder `self.mod_euc(rhs)` by Euclidean division. Returns a tuple of the modulo after dividing along with a boolean indicating whether an arithmetic overflow would occur. Note that for @@ -3070,7 +3071,8 @@ This function will panic if `rhs` is 0. Basic usage ``` -", $Feature, "assert_eq!(5", stringify!($SelfT), ".overflowing_mod_euc(2), (1, false));", $EndFeature, " +", $Feature, "assert_eq!(5", stringify!($SelfT), ".overflowing_mod_euc(2), (1, false));", +$EndFeature, " ```"), #[inline] #[unstable(feature = "euclidean_division", issue = "49048")] @@ -3259,7 +3261,7 @@ $EndFeature, " doc_comment! { - concat!("Calculates the Euclidean modulo `self mod rhs`. + concat!("Calculates the remainder `self mod rhs` by Euclidean division. For unsigned types, this is just the same as `self % rhs`. diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index ed63f44508462..ca39089a9583a 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -331,9 +331,9 @@ impl f32 { /// Calculates Euclidean division, the matching method for `mod_euc`. /// - /// This computes the integer n such that + /// 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 + /// In other words, the result is `self / rhs` rounded to the integer `n` /// such that `self >= n * rhs`. /// /// ``` diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index 320655c443c6a..a9585670ad043 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -317,9 +317,9 @@ impl f64 { /// Calculates Euclidean division, the matching method for `mod_euc`. /// - /// This computes the integer n such that + /// 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 + /// In other words, the result is `self / rhs` rounded to the integer `n` /// such that `self >= n * rhs`. /// /// ``` From 1b5db85314a35416b617e8b7d0a3baa72922a2f3 Mon Sep 17 00:00:00 2001 From: Fabian Zaiser Date: Wed, 28 Mar 2018 16:22:37 +0200 Subject: [PATCH 3/5] Fix #![feature]s. --- src/libcore/num/mod.rs | 77 ++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 9e7e935715952..1346435a21a4d 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -642,11 +642,11 @@ returning `None` if `rhs == 0` or the division results in overflow. Basic usage: ``` -", $Feature, "assert_eq!((", stringify!($SelfT), +#![feature(euclidean_division)] +assert_eq!((", stringify!($SelfT), "::min_value() + 1).checked_div_euc(-1), Some(", stringify!($Max), ")); assert_eq!(", stringify!($SelfT), "::min_value().checked_div_euc(-1), None); -assert_eq!((1", stringify!($SelfT), ").checked_div_euc(0), None);", -$EndFeature, " +assert_eq!((1", stringify!($SelfT), ").checked_div_euc(0), None); ```"), #[unstable(feature = "euclidean_division", issue = "49048")] #[inline] @@ -695,12 +695,12 @@ $EndFeature, " Basic usage: ``` -", $Feature, "use std::", stringify!($SelfT), "; +#![feature(euclidean_division)] +use std::", stringify!($SelfT), "; assert_eq!(5", stringify!($SelfT), ".checked_mod_euc(2), Some(1)); assert_eq!(5", stringify!($SelfT), ".checked_mod_euc(0), None); -assert_eq!(", stringify!($SelfT), "::MIN.checked_mod_euc(-1), None);", -$EndFeature, " +assert_eq!(", stringify!($SelfT), "::MIN.checked_mod_euc(-1), None); ```"), #[unstable(feature = "euclidean_division", issue = "49048")] #[inline] @@ -1063,9 +1063,9 @@ This function will panic if `rhs` is 0. Basic usage: ``` +#![feature(euclidean_division)] assert_eq!(100", stringify!($SelfT), ".wrapping_div_euc(10), 10); -assert_eq!((-128i8).wrapping_div_euc(-1), -128);", -$EndFeature, " +assert_eq!((-128i8).wrapping_div_euc(-1), -128); ```"), #[unstable(feature = "euclidean_division", issue = "49048")] #[inline] @@ -1119,9 +1119,9 @@ This function will panic if `rhs` is 0. Basic usage: ``` -", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_mod_euc(10), 0); -assert_eq!((-128i8).wrapping_mod_euc(-1), 0);", -$EndFeature, " +#![feature(euclidean_division)] +assert_eq!(100", stringify!($SelfT), ".wrapping_mod_euc(10), 0); +assert_eq!((-128i8).wrapping_mod_euc(-1), 0); ```"), #[unstable(feature = "euclidean_division", issue = "49048")] #[inline] @@ -1410,12 +1410,12 @@ This function will panic if `rhs` is 0. Basic usage: ``` -", $Feature, "use std::", stringify!($SelfT), "; +#![feature(euclidean_division)] +use std::", stringify!($SelfT), "; assert_eq!(5", stringify!($SelfT), ".overflowing_div_euc(2), (2, false)); assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div_euc(-1), (", stringify!($SelfT), -"::MIN, true));", -$EndFeature, " +"::MIN, true)); ```"), #[inline] #[unstable(feature = "euclidean_division", issue = "49048")] @@ -1476,11 +1476,11 @@ This function will panic if `rhs` is 0. Basic usage: ``` -", $Feature, "use std::", stringify!($SelfT), "; +#![feature(euclidean_division)] +use std::", stringify!($SelfT), "; assert_eq!(5", stringify!($SelfT), ".overflowing_mod_euc(2), (1, false)); -assert_eq!(", stringify!($SelfT), "::MIN.overflowing_mod_euc(-1), (0, true));", -$EndFeature, " +assert_eq!(", stringify!($SelfT), "::MIN.overflowing_mod_euc(-1), (0, true)); ```"), #[unstable(feature = "euclidean_division", issue = "49048")] #[inline] @@ -1704,14 +1704,14 @@ This function will panic if `rhs` is 0. Basic usage: ``` -", $Feature, "let a: ", stringify!($SelfT), " = 7; // or any other integer type +#![feature(euclidean_division)] +let a: ", stringify!($SelfT), " = 7; // or any other integer type let b = 4; assert_eq!(a.div_euc(b), 1); // 7 >= 4 * 1 assert_eq!(a.div_euc(-b), -1); // 7 >= -4 * -1 assert_eq!((-a).div_euc(b), -2); // -7 >= 4 * -2 -assert_eq!((-a).div_euc(-b), 2); // -7 >= -4 * 2", -$EndFeature, " +assert_eq!((-a).div_euc(-b), 2); // -7 >= -4 * 2 ```"), #[unstable(feature = "euclidean_division", issue = "49048")] #[inline] @@ -1740,14 +1740,14 @@ This function will panic if `rhs` is 0. Basic usage: ``` -", $Feature, "let a: ", stringify!($SelfT), " = 7; // or any other integer type +#![feature(euclidean_division)] +let a: ", stringify!($SelfT), " = 7; // or any other integer type let b = 4; assert_eq!(a.mod_euc(b), 3); assert_eq!((-a).mod_euc(b), 1); assert_eq!(a.mod_euc(-b), 3); -assert_eq!((-a).mod_euc(-b), 1);", -$EndFeature, " +assert_eq!((-a).mod_euc(-b), 1); ```"), #[unstable(feature = "euclidean_division", issue = "49048")] #[inline] @@ -2362,7 +2362,8 @@ if `rhs == 0`. Basic usage: ``` -", $Feature, "assert_eq!(128", stringify!($SelfT), ".checked_div(2), Some(64)); +#![feature(euclidean_division)] +assert_eq!(128", stringify!($SelfT), ".checked_div(2), Some(64)); assert_eq!(1", stringify!($SelfT), ".checked_div_euc(0), None); ```"), #[unstable(feature = "euclidean_division", issue = "49048")] @@ -2409,9 +2410,9 @@ if `rhs == 0`. Basic usage: ``` -", $Feature, "assert_eq!(5", stringify!($SelfT), ".checked_mod_euc(2), Some(1)); -assert_eq!(5", stringify!($SelfT), ".checked_mod_euc(0), None);", -$EndFeature, " +#![feature(euclidean_division)] +assert_eq!(5", stringify!($SelfT), ".checked_mod_euc(2), Some(1)); +assert_eq!(5", stringify!($SelfT), ".checked_mod_euc(0), None); ```"), #[unstable(feature = "euclidean_division", issue = "49048")] #[inline] @@ -2715,7 +2716,8 @@ are accounted for in the wrapping operations. Basic usage: ``` -", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_div_euc(10), 10);", $EndFeature, " +#![feature(euclidean_division)] +assert_eq!(100", stringify!($SelfT), ".wrapping_div_euc(10), 10); ```"), #[unstable(feature = "euclidean_division", issue = "49048")] #[inline] @@ -2759,7 +2761,8 @@ are accounted for in the wrapping operations. Basic usage: ``` -", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_mod_euc(10), 0);", $EndFeature, " +#![feature(euclidean_division)] +assert_eq!(100", stringify!($SelfT), ".wrapping_mod_euc(10), 0); ```"), #[unstable(feature = "euclidean_division", issue = "49048")] #[inline] @@ -3018,8 +3021,8 @@ This function will panic if `rhs` is 0. Basic usage ``` -", $Feature, "assert_eq!(5", stringify!($SelfT), ".overflowing_div_euc(2), (2, false));", -$EndFeature, " +#![feature(euclidean_division)] +assert_eq!(5", stringify!($SelfT), ".overflowing_div_euc(2), (2, false)); ```"), #[inline] #[unstable(feature = "euclidean_division", issue = "49048")] @@ -3071,8 +3074,8 @@ This function will panic if `rhs` is 0. Basic usage ``` -", $Feature, "assert_eq!(5", stringify!($SelfT), ".overflowing_mod_euc(2), (1, false));", -$EndFeature, " +#![feature(euclidean_division)] +assert_eq!(5", stringify!($SelfT), ".overflowing_mod_euc(2), (1, false)); ```"), #[inline] #[unstable(feature = "euclidean_division", issue = "49048")] @@ -3248,8 +3251,8 @@ For unsigned types, this is just the same as `self / rhs`. Basic usage: ``` -", $Feature, "assert_eq(7", stringify!($SelfT), ".div_euc(4), 1); // or any other integer type", -$EndFeature, " +#![feature(euclidean_division)] +assert_eq(7", stringify!($SelfT), ".div_euc(4), 1); // or any other integer type ```"), #[unstable(feature = "euclidean_division", issue = "49048")] #[inline] @@ -3270,8 +3273,8 @@ For unsigned types, this is just the same as `self % rhs`. Basic usage: ``` -", $Feature, "assert_eq(7", stringify!($SelfT), ".mod_euc(4), 3); // or any other integer type", -$EndFeature, " +#![feature(euclidean_division)] +assert_eq(7", stringify!($SelfT), ".mod_euc(4), 3); // or any other integer type ```"), #[unstable(feature = "euclidean_division", issue = "49048")] #[inline] From c0870e2f55b8b160c8ad7af684831902b4979cfb Mon Sep 17 00:00:00 2001 From: Fabian Zaiser Date: Thu, 29 Mar 2018 01:10:37 +0200 Subject: [PATCH 4/5] Fix doctest (typo). --- src/libcore/num/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 1346435a21a4d..89276fcee809d 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -3252,7 +3252,7 @@ Basic usage: ``` #![feature(euclidean_division)] -assert_eq(7", stringify!($SelfT), ".div_euc(4), 1); // or any other integer type +assert_eq!(7", stringify!($SelfT), ".div_euc(4), 1); // or any other integer type ```"), #[unstable(feature = "euclidean_division", issue = "49048")] #[inline] @@ -3274,7 +3274,7 @@ Basic usage: ``` #![feature(euclidean_division)] -assert_eq(7", stringify!($SelfT), ".mod_euc(4), 3); // or any other integer type +assert_eq!(7", stringify!($SelfT), ".mod_euc(4), 3); // or any other integer type ```"), #[unstable(feature = "euclidean_division", issue = "49048")] #[inline] From ca4e458089d0fecb8684de0437534d5f40b003bf Mon Sep 17 00:00:00 2001 From: Fabian Zaiser Date: Thu, 12 Apr 2018 23:12:11 +0200 Subject: [PATCH 5/5] Address more nits. --- src/libcore/num/mod.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 89276fcee809d..d11ee7cf740fa 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1050,9 +1050,9 @@ $EndFeature, " concat!("Wrapping Euclidean division. Computes `self.div_euc(rhs)`, wrapping around at the boundary of the type. -The only case where such wrapping can occur is when one divides `MIN / -1` on a signed type (where -`MIN` is the negative minimal value for the type); this is equivalent to `-MIN`, a positive value -that is too large to represent in the type. In such a case, this function returns `MIN` itself. +Wrapping will only occur in `MIN / -1` on a signed type (where `MIN` is the negative minimal value +for the type). This is equivalent to `-MIN`, a positive value that is too large to represent in the +type. In this case, this method returns `MIN` itself. # Panics @@ -1106,9 +1106,8 @@ $EndFeature, " concat!("Wrapping Euclidean modulo. Computes `self.mod_euc(rhs)`, wrapping around at the boundary of the type. -Such wrap-around never actually occurs mathematically; implementation artifacts make `x % y` -invalid for `MIN / -1` on a signed type (where `MIN` is the negative minimal value). In such a case, -this function returns `0`. +Wrapping will only occur in `MIN % -1` on a signed type (where `MIN` is the negative minimal value +for the type). In this case, this method returns 0. # Panics @@ -1399,7 +1398,7 @@ $EndFeature, " concat!("Calculates the quotient of Euclidean division `self.div_euc(rhs)`. Returns a tuple of the divisor along with a boolean indicating whether an arithmetic overflow would -occur. If an overflow would occur then self is returned. +occur. If an overflow would occur then `self` is returned. # Panics