Explorar o código

Fixes methods

SparrowLii %!s(int64=4) %!d(string=hai) anos
pai
achega
b29d99b837
Modificáronse 2 ficheiros con 175 adicións e 79 borrados
  1. 1 1
      src/lib.rs
  2. 174 78
      src/ops/euclid.rs

+ 1 - 1
src/lib.rs

@@ -40,7 +40,7 @@ pub use int::PrimInt;
 pub use ops::checked::{
     CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub,
 };
-pub use ops::euclid::{CheckedDivRemEuclid, DivRemEuclid};
+pub use ops::euclid::{CheckedDivEuclid, CheckedRemEuclid, DivEuclid, RemEuclid};
 pub use ops::inv::Inv;
 pub use ops::mul_add::{MulAdd, MulAddAssign};
 pub use ops::saturating::{Saturating, SaturatingAdd, SaturatingMul, SaturatingSub};

+ 174 - 78
src/ops/euclid.rs

@@ -1,85 +1,132 @@
 use core::ops::{Div, Rem};
-pub trait DivRemEuclid: Sized + Div<Self, Output = Self> + Rem<Self, Output = Self> {
+pub trait DivEuclid: Sized + Div<Self, Output = Self> {
     /// Calculates Euclidean division, the matching method for `rem_euclid`.
     ///
     /// This computes the integer `n` such that
-    /// `self = n * rhs + self.rem_euclid(rhs)`.
-    /// In other words, the result is `self / rhs` rounded to the integer `n`
-    /// such that `self >= n * rhs`.
+    /// `self = n * v + self.rem_euclid(v)`.
+    /// In other words, the result is `self / v` rounded to the integer `n`
+    /// such that `self >= n * v`.
     ///
     /// # Examples
     ///
     /// ```
-    /// use num_traits::DivRemEuclid;
+    /// use num_traits::DivEuclid;
     ///
     /// let a: i32 = 7;
     /// let b: i32 = 4;
-    /// assert_eq!(DivRemEuclid::div_euclid(&a,&b), 1); // 7 > 4 * 1
-    /// assert_eq!(DivRemEuclid::div_euclid(&-a,&b), -2); // -7 >= 4 * -2
-    /// assert_eq!(DivRemEuclid::div_euclid(&a,&-b), -1); // 7 >= -4 * -1
-    /// assert_eq!(DivRemEuclid::div_euclid(&-a,&-b), 2); // -7 >= -4 * 2
+    /// assert_eq!(DivEuclid::div_euclid(a,b), 1); // 7 > 4 * 1
+    /// assert_eq!(DivEuclid::div_euclid(-a,b), -2); // -7 >= 4 * -2
+    /// assert_eq!(DivEuclid::div_euclid(a,-b), -1); // 7 >= -4 * -1
+    /// assert_eq!(DivEuclid::div_euclid(-a,-b), 2); // -7 >= -4 * 2
     /// ```
-    fn div_euclid(&self, v: &Self) -> Self;
-
-    /// Calculates the least nonnegative remainder of `self (mod rhs)`.
+    fn div_euclid(self, v: Self) -> Self;
+}
+pub trait RemEuclid: Sized + Rem<Self, Output = Self> {
+    /// Calculates the least nonnegative remainder of `self (mod v)`.
     ///
-    /// In particular, the return value `r` satisfies `0.0 <= r < rhs.abs()` in
+    /// In particular, the return value `r` satisfies `0.0 <= r < v.abs()` in
     /// most cases. However, due to a floating point round-off error it can
-    /// result in `r == rhs.abs()`, violating the mathematical definition, if
-    /// `self` is much smaller than `rhs.abs()` in magnitude and `self < 0.0`.
+    /// result in `r == v.abs()`, violating the mathematical definition, if
+    /// `self` is much smaller than `v.abs()` in magnitude and `self < 0.0`.
     /// This result is not an element of the function's codomain, but it is the
     /// closest floating point number in the real numbers and thus fulfills the
-    /// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)`
+    /// property `self == self.div_euclid(v) * v + self.rem_euclid(v)`
     /// approximatively.
     ///
     /// # Examples
     ///
     /// ```
-    /// use num_traits::DivRemEuclid;
+    /// use num_traits::RemEuclid;
     ///
     /// let a: i32 = 7;
     /// let b: i32 = 4;
-    /// assert_eq!(DivRemEuclid::rem_euclid(&a,&b), 3);
-    /// assert_eq!(DivRemEuclid::rem_euclid(&-a,&b), 1);
-    /// assert_eq!(DivRemEuclid::rem_euclid(&a,&-b), 3);
-    /// assert_eq!(DivRemEuclid::rem_euclid(&-a,&-b), 1);
+    /// assert_eq!(RemEuclid::rem_euclid(a,b), 3);
+    /// assert_eq!(RemEuclid::rem_euclid(-a,b), 1);
+    /// assert_eq!(RemEuclid::rem_euclid(a,-b), 3);
+    /// assert_eq!(RemEuclid::rem_euclid(-a,-b), 1);
     /// ```
-    fn rem_euclid(&self, v: &Self) -> Self;
+    fn rem_euclid(self, v: Self) -> Self;
 }
-macro_rules! div_rem_euclid_impl {
-    ($trait_name:ident,$method:ident,$method_2:ident for $($t:ty)*) => {$(
+macro_rules! div_euclid_int_impl {
+    ($trait_name:ident for $($t:ty)*) => {$(
         impl $trait_name for $t {
             #[inline]
-            fn $method(&self, v: &$t) -> Self {
-                <$t>::$method(*self, *v)
+            fn div_euclid(self, v: $t) -> Self {
+                let q = self / v;
+                if self % v < 0 {
+                    return if v > 0 { q - 1 } else { q + 1 }
+                }
+                q
             }
-
+        }
+    )*}
+}
+macro_rules! div_euclid_uint_impl {
+    ($trait_name:ident for $($t:ty)*) => {$(
+        impl $trait_name for $t {
             #[inline]
-            fn $method_2(&self, v: &$t) -> Self {
-                <$t>::$method_2(*self, *v)
+            fn div_euclid(self, v: $t) -> Self {
+                self / v
             }
-
         }
     )*}
 }
-div_rem_euclid_impl!(DivRemEuclid,div_euclid,rem_euclid for isize usize i8 u8 i16 u16 i32 u32 i64 u64);
+macro_rules! rem_euclid_int_impl {
+    ($trait_name:ident for $($t:ty)*) => {$(
+        impl $trait_name for $t {
+            #[inline]
+            fn rem_euclid(self, v: $t) -> Self {
+                let r = self % v;
+                if r < 0 {
+                    if v < 0 {
+                        r - v
+                    } else {
+                        r + v
+                    }
+                } else {
+                    r
+                }
+            }
+        }
+    )*}
+}
+macro_rules! rem_euclid_uint_impl {
+    ($trait_name:ident for $($t:ty)*) => {$(
+        impl $trait_name for $t {
+            #[inline]
+            fn rem_euclid(self, v: $t) -> Self {
+                self % v
+            }
+        }
+    )*}
+}
+div_euclid_int_impl!(DivEuclid for i8 i16 i32 i64);
+div_euclid_uint_impl!(DivEuclid for isize usize u8 u16 u32 u64);
+rem_euclid_int_impl!(RemEuclid for i8 i16 i32 i64);
+rem_euclid_uint_impl!(RemEuclid for isize usize u8 u16 u32 u64);
 #[cfg(has_i128)]
-div_rem_euclid_impl!(DivRemEuclid,div_euclid,rem_euclid for i128 u128);
+div_euclid_int_impl!(DivEuclid for i128);
+div_euclid_uint_impl!(DivEuclid for u128);
+rem_euclid_int_impl!(RemEuclid for i128);
+rem_euclid_uint_impl!(RemEuclid for u128);
 
 #[cfg(any(feature = "std", feature = "libm"))]
-impl DivRemEuclid for f32 {
-    fn div_euclid(&self, rhs: &f32) -> f32 {
-        let q = <f32 as ::Float>::trunc(self / rhs);
-        if self % rhs < 0.0 {
-            return if *rhs > 0.0 { q - 1.0 } else { q + 1.0 };
+impl DivEuclid for f32 {
+    fn div_euclid(self, v: f32) -> f32 {
+        let q = <f32 as ::Float>::trunc(self / v);
+        if self % v < 0.0 {
+            return if v > 0.0 { q - 1.0 } else { q + 1.0 };
         }
         q
     }
+}
 
-    fn rem_euclid(&self, rhs: &f32) -> f32 {
-        let r = self % rhs;
+#[cfg(any(feature = "std", feature = "libm"))]
+impl RemEuclid for f32 {
+    fn rem_euclid(self, v: f32) -> f32 {
+        let r = self % v;
         if r < 0.0 {
-            r + <f32 as ::Float>::abs(*rhs)
+            r + <f32 as ::Float>::abs(v)
         } else {
             r
         }
@@ -87,53 +134,102 @@ impl DivRemEuclid for f32 {
 }
 
 #[cfg(any(feature = "std", feature = "libm"))]
-impl DivRemEuclid for f64 {
-    fn div_euclid(&self, rhs: &f64) -> f64 {
-        let q = <f64 as ::Float>::trunc(self / rhs);
-        if self % rhs < 0.0 {
-            return if *rhs > 0.0 { q - 1.0 } else { q + 1.0 };
+impl DivEuclid for f64 {
+    fn div_euclid(self, v: f64) -> f64 {
+        let q = <f64 as ::Float>::trunc(self / v);
+        if self % v < 0.0 {
+            return if v > 0.0 { q - 1.0 } else { q + 1.0 };
         }
         q
     }
-
-    fn rem_euclid(&self, rhs: &f64) -> f64 {
-        let r = self % rhs;
+}
+#[cfg(any(feature = "std", feature = "libm"))]
+impl RemEuclid for f64 {
+    fn rem_euclid(self, v: f64) -> f64 {
+        let r = self % v;
         if r < 0.0 {
-            r + <f64 as ::Float>::abs(*rhs)
+            r + <f64 as ::Float>::abs(v)
         } else {
             r
         }
     }
 }
 
-pub trait CheckedDivRemEuclid: Sized + Div<Self, Output = Self> + Rem<Self, Output = Self> {
+pub trait CheckedDivEuclid: DivEuclid {
     /// Performs euclid division that returns `None` instead of panicking on division by zero
     /// and instead of wrapping around on underflow and overflow.
-    fn checked_div_euclid(&self, v: &Self) -> Option<Self>;
-
+    fn checked_div_euclid(self, v: Self) -> Option<Self>;
+}
+pub trait CheckedRemEuclid: RemEuclid {
     /// Finds the euclid remainder of dividing two numbers, checking for underflow, overflow and
     /// division by zero. If any of that happens, `None` is returned.
-    fn checked_rem_euclid(&self, v: &Self) -> Option<Self>;
+    fn checked_rem_euclid(self, v: Self) -> Option<Self>;
 }
-
-macro_rules! checked_div_rem_euclid_impl {
-    ($trait_name:ident,$method:ident,$method_2:ident for $($t:ty)*) => {$(
+macro_rules! checked_div_euclid_int_impl {
+    ($trait_name:ident for $($t:ty)*) => {$(
         impl $trait_name for $t {
             #[inline]
-            fn $method(&self, v: &$t) -> Option<$t> {
-                <$t>::$method(*self, *v)
+            fn checked_div_euclid(self, v: $t) -> Option<$t> {
+                if v == 0 || (self == Self::MIN && v == -1) {
+                    None
+                } else {
+                    Some(DivEuclid::div_euclid(self,v))
+                }
             }
-
+        }
+    )*}
+}
+macro_rules! checked_div_euclid_uint_impl {
+    ($trait_name:ident for $($t:ty)*) => {$(
+        impl $trait_name for $t {
+            #[inline]
+            fn checked_div_euclid(self, v: $t) -> Option<$t> {
+                if v == 0{
+                    None
+                } else {
+                    Some(DivEuclid::div_euclid(self,v))
+                }
+            }
+        }
+    )*}
+}
+macro_rules! checked_rem_euclid_int_impl {
+    ($trait_name:ident for $($t:ty)*) => {$(
+        impl $trait_name for $t {
+            #[inline]
+            fn checked_rem_euclid(self, v: $t) -> Option<$t> {
+                if v == 0 || (self == Self::MIN && v == -1) {
+                    None
+                } else {
+                    Some(RemEuclid::rem_euclid(self,v))
+                }
+            }
+        }
+    )*}
+}
+macro_rules! checked_rem_euclid_uint_impl {
+    ($trait_name:ident for $($t:ty)*) => {$(
+        impl $trait_name for $t {
             #[inline]
-            fn $method_2(&self, v: &$t) -> Option<$t> {
-                <$t>::$method_2(*self, *v)
+            fn checked_rem_euclid(self, v: $t) -> Option<$t> {
+                if v == 0{
+                    None
+                } else {
+                    Some(RemEuclid::rem_euclid(self,v))
+                }
             }
         }
     )*}
 }
-checked_div_rem_euclid_impl!(CheckedDivRemEuclid,checked_div_euclid,checked_rem_euclid for isize usize i8 u8 i16 u16 i32 u32 i64 u64);
+checked_div_euclid_int_impl!(CheckedDivEuclid for i8 i16 i32 i64);
+checked_div_euclid_uint_impl!(CheckedDivEuclid for isize usize u8 u16 u32 u64);
+checked_rem_euclid_int_impl!(CheckedRemEuclid for i8 i16 i32 i64);
+checked_rem_euclid_uint_impl!(CheckedRemEuclid for isize usize u8 u16 u32 u64);
 #[cfg(has_i128)]
-checked_div_rem_euclid_impl!(CheckedDivRemEuclid,checked_div_euclid,checked_rem_euclid for i128 u128);
+checked_div_euclid_int_impl!(CheckedDivEuclid for i128);
+checked_div_euclid_uint_impl!(CheckedDivEuclid for u128);
+checked_rem_euclid_int_impl!(CheckedRemEuclid for i128);
+checked_rem_euclid_uint_impl!(CheckedRemEuclid for u128);
 
 #[cfg(test)]
 mod tests {
@@ -147,8 +243,8 @@ mod tests {
                     {
                         let x: $t = 10;
                         let y: $t = 3;
-                        assert_eq!(DivRemEuclid::div_euclid(&x,&y),3);
-                        assert_eq!(DivRemEuclid::rem_euclid(&x,&y),1);
+                        assert_eq!(DivEuclid::div_euclid(x,y),3);
+                        assert_eq!(RemEuclid::rem_euclid(x,y),1);
                     }
                 )+
             };
@@ -165,13 +261,13 @@ mod tests {
                     {
                         let x: $t = 10;
                         let y: $t = -3;
-                        assert_eq!(DivRemEuclid::div_euclid(&x,&y),-3);
-                        assert_eq!(DivRemEuclid::div_euclid(&-x,&y),4);
-                        assert_eq!(DivRemEuclid::rem_euclid(&x,&y),1);
-                        assert_eq!(DivRemEuclid::rem_euclid(&-x,&y),2);
+                        assert_eq!(DivEuclid::div_euclid(x,y),-3);
+                        assert_eq!(DivEuclid::div_euclid(-x,y),4);
+                        assert_eq!(RemEuclid::rem_euclid(x,y),1);
+                        assert_eq!(RemEuclid::rem_euclid(-x,y),2);
                         let x: $t = $t::MIN+1;
                         let y: $t = -1;
-                        assert_eq!(DivRemEuclid::div_euclid(&x,&y),$t::MAX);
+                        assert_eq!(DivEuclid::div_euclid(x,y),$t::MAX);
                     }
                 )+
             };
@@ -189,13 +285,13 @@ mod tests {
                     {
                         let x: $t = 12.1;
                         let y: $t = 3.2;
-                        assert!(DivRemEuclid::div_euclid(&x,&y)*y+DivRemEuclid::rem_euclid(&x,&y)-x
+                        assert!(DivEuclid::div_euclid(x,y)*y+RemEuclid::rem_euclid(x,y)-x
                         <=46.4 * $t::EPSILON);
-                        assert!(DivRemEuclid::div_euclid(&x,&-y)*-y+DivRemEuclid::rem_euclid(&x,&-y)-x
+                        assert!(DivEuclid::div_euclid(x,-y)*-y+RemEuclid::rem_euclid(x,-y)-x
                         <= 46.4 * $t::EPSILON);
-                        assert!(DivRemEuclid::div_euclid(&-x,&y)*y+DivRemEuclid::rem_euclid(&-x,&y)-(-x)
+                        assert!(DivEuclid::div_euclid(-x,y)*y+RemEuclid::rem_euclid(-x,y)-(-x)
                         <= 46.4 * $t::EPSILON);
-                        assert!(DivRemEuclid::div_euclid(&-x,&-y)*-y+DivRemEuclid::rem_euclid(&-x,&-y)-(-x)
+                        assert!(DivEuclid::div_euclid(-x,-y)*-y+RemEuclid::rem_euclid(-x,-y)-(-x)
                         <= 46.4 * $t::EPSILON);
                     }
                 )+
@@ -211,10 +307,10 @@ mod tests {
             ($($t:ident)+) => {
                 $(
                     {
-                        assert_eq!(CheckedDivRemEuclid::checked_div_euclid(&$t::MIN,&-1),None);
-                        assert_eq!(CheckedDivRemEuclid::checked_rem_euclid(&$t::MIN,&-1),None);
-                        assert_eq!(CheckedDivRemEuclid::checked_div_euclid(&1,&0),None);
-                        assert_eq!(CheckedDivRemEuclid::checked_rem_euclid(&1,&0),None);
+                        assert_eq!(CheckedDivEuclid::checked_div_euclid($t::MIN,-1),None);
+                        assert_eq!(CheckedRemEuclid::checked_rem_euclid($t::MIN,-1),None);
+                        assert_eq!(CheckedDivEuclid::checked_div_euclid(1,0),None);
+                        assert_eq!(CheckedRemEuclid::checked_rem_euclid(1,0),None);
                     }
                 )+
             };