fixes codes structure etc.

This commit is contained in:
SparrowLii
2020-11-16 16:50:14 +08:00
committed by Josh Stone
parent a0a6154a75
commit 7ece7edabf
2 changed files with 87 additions and 122 deletions
+3 -1
View File
@@ -33,6 +33,7 @@ pub use bounds::Bounded;
#[cfg(any(feature = "std", feature = "libm"))]
pub use float::Float;
pub use float::FloatConst;
pub use float::FloatCore;
// pub use real::{FloatCore, Real}; // NOTE: Don't do this, it breaks `use num_traits::*;`.
pub use cast::{cast, AsPrimitive, FromPrimitive, NumCast, ToPrimitive};
pub use identities::{one, zero, One, Zero};
@@ -40,7 +41,7 @@ pub use int::PrimInt;
pub use ops::checked::{
CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub,
};
pub use ops::euclid::{CheckedDivEuclid, CheckedRemEuclid, DivEuclid, RemEuclid};
pub use ops::euclid::{CheckedEuclid, Euclid};
pub use ops::inv::Inv;
pub use ops::mul_add::{MulAdd, MulAddAssign};
pub use ops::saturating::{Saturating, SaturatingAdd, SaturatingMul, SaturatingSub};
@@ -49,6 +50,7 @@ pub use ops::wrapping::{
};
pub use pow::{checked_pow, pow, Pow};
pub use sign::{abs, abs_sub, signum, Signed, Unsigned};
#[macro_use]
mod macros;
+84 -121
View File
@@ -1,5 +1,6 @@
use core::ops::{Div, Rem};
pub trait DivEuclid: Sized + Div<Self, Output = Self> {
pub trait Euclid: Sized + Div<Self, Output = Self> + Rem<Self, Output = Self> {
/// Calculates Euclidean division, the matching method for `rem_euclid`.
///
/// This computes the integer `n` such that
@@ -10,18 +11,17 @@ pub trait DivEuclid: Sized + Div<Self, Output = Self> {
/// # Examples
///
/// ```
/// use num_traits::DivEuclid;
/// use num_traits::Euclid;
///
/// let a: i32 = 7;
/// let b: i32 = 4;
/// 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
/// assert_eq!(Euclid::div_euclid(a, b), 1); // 7 > 4 * 1
/// assert_eq!(Euclid::div_euclid(-a, b), -2); // -7 >= 4 * -2
/// assert_eq!(Euclid::div_euclid(a, -b), -1); // 7 >= -4 * -1
/// assert_eq!(Euclid::div_euclid(-a, -b), 2); // -7 >= -4 * 2
/// ```
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 < v.abs()` in
@@ -36,20 +36,20 @@ pub trait RemEuclid: Sized + Rem<Self, Output = Self> {
/// # Examples
///
/// ```
/// use num_traits::RemEuclid;
/// use num_traits::Euclid;
///
/// let a: i32 = 7;
/// let b: i32 = 4;
/// 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);
/// assert_eq!(Euclid::rem_euclid(a, b), 3);
/// assert_eq!(Euclid::rem_euclid(-a, b), 1);
/// assert_eq!(Euclid::rem_euclid(a, -b), 3);
/// assert_eq!(Euclid::rem_euclid(-a, -b), 1);
/// ```
fn rem_euclid(self, v: Self) -> Self;
}
macro_rules! div_euclid_int_impl {
($trait_name:ident for $($t:ty)*) => {$(
impl $trait_name for $t {
macro_rules! euclid_int_impl {
($($t:ty)*) => {$(
impl Euclid for $t {
#[inline]
fn div_euclid(self, v: $t) -> Self {
let q = self / v;
@@ -58,22 +58,7 @@ macro_rules! div_euclid_int_impl {
}
q
}
}
)*}
}
macro_rules! div_euclid_uint_impl {
($trait_name:ident for $($t:ty)*) => {$(
impl $trait_name for $t {
#[inline]
fn div_euclid(self, v: $t) -> Self {
self / v
}
}
)*}
}
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;
@@ -90,9 +75,14 @@ macro_rules! rem_euclid_int_impl {
}
)*}
}
macro_rules! rem_euclid_uint_impl {
($trait_name:ident for $($t:ty)*) => {$(
impl $trait_name for $t {
macro_rules! euclid_uint_impl {
($($t:ty)*) => {$(
impl Euclid for $t {
#[inline]
fn div_euclid(self, v: $t) -> Self {
self / v
}
#[inline]
fn rem_euclid(self, v: $t) -> Self {
self % v
@@ -100,142 +90,116 @@ macro_rules! rem_euclid_uint_impl {
}
)*}
}
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);
euclid_int_impl!(isize i8 i16 i32 i64);
euclid_uint_impl!(usize u8 u16 u32 u64);
#[cfg(has_i128)]
div_euclid_int_impl!(DivEuclid for i128);
euclid_int_impl!(i128);
#[cfg(has_i128)]
div_euclid_uint_impl!(DivEuclid for u128);
#[cfg(has_i128)]
rem_euclid_int_impl!(RemEuclid for i128);
#[cfg(has_i128)]
rem_euclid_uint_impl!(RemEuclid for u128);
euclid_uint_impl!(u128);
#[cfg(any(feature = "std", feature = "libm"))]
impl DivEuclid for f32 {
impl Euclid for f32 {
#[inline]
fn div_euclid(self, v: f32) -> f32 {
let q = <f32 as ::Float>::trunc(self / v);
let q = <f32 as ::FloatCore>::trunc(self / v);
if self % v < 0.0 {
return if v > 0.0 { q - 1.0 } else { q + 1.0 };
}
q
}
}
#[cfg(any(feature = "std", feature = "libm"))]
impl RemEuclid for f32 {
#[inline]
fn rem_euclid(self, v: f32) -> f32 {
let r = self % v;
if r < 0.0 {
r + <f32 as ::Float>::abs(v)
r + <f32 as ::FloatCore>::abs(v)
} else {
r
}
}
}
#[cfg(any(feature = "std", feature = "libm"))]
impl DivEuclid for f64 {
impl Euclid for f64 {
#[inline]
fn div_euclid(self, v: f64) -> f64 {
let q = <f64 as ::Float>::trunc(self / v);
let q = <f64 as ::FloatCore>::trunc(self / v);
if self % v < 0.0 {
return if v > 0.0 { q - 1.0 } else { q + 1.0 };
}
q
}
}
#[cfg(any(feature = "std", feature = "libm"))]
impl RemEuclid for f64 {
#[inline]
fn rem_euclid(self, v: f64) -> f64 {
let r = self % v;
if r < 0.0 {
r + <f64 as ::Float>::abs(v)
r + <f64 as ::FloatCore>::abs(v)
} else {
r
}
}
}
pub trait CheckedDivEuclid: DivEuclid {
pub trait CheckedEuclid: Euclid {
/// 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>;
}
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>;
}
macro_rules! checked_div_euclid_int_impl {
($trait_name:ident for $($t:ty)*) => {$(
impl $trait_name for $t {
macro_rules! checked_euclid_int_impl {
($($t:ty)*) => {$(
impl CheckedEuclid for $t {
#[inline]
fn checked_div_euclid(self, v: $t) -> Option<$t> {
if v == 0 || (self == Self::min_value() && v == -1) {
None
} else {
Some(DivEuclid::div_euclid(self,v))
Some(Euclid::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_value() && v == -1) {
None
} else {
Some(RemEuclid::rem_euclid(self,v))
Some(Euclid::rem_euclid(self, v))
}
}
}
)*}
}
macro_rules! checked_rem_euclid_uint_impl {
($trait_name:ident for $($t:ty)*) => {$(
impl $trait_name for $t {
macro_rules! checked_euclid_uint_impl {
($($t:ty)*) => {$(
impl CheckedEuclid for $t {
#[inline]
fn checked_div_euclid(self, v: $t) -> Option<$t> {
if v == 0{
None
} else {
Some(Euclid::div_euclid(self, v))
}
}
#[inline]
fn checked_rem_euclid(self, v: $t) -> Option<$t> {
if v == 0{
None
} else {
Some(RemEuclid::rem_euclid(self,v))
Some(Euclid::rem_euclid(self, v))
}
}
}
)*}
}
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);
checked_euclid_int_impl!(isize i8 i16 i32 i64);
checked_euclid_uint_impl!(usize u8 u16 u32 u64);
#[cfg(has_i128)]
checked_div_euclid_int_impl!(CheckedDivEuclid for i128);
checked_euclid_int_impl!(i128);
#[cfg(has_i128)]
checked_div_euclid_uint_impl!(CheckedDivEuclid for u128);
#[cfg(has_i128)]
checked_rem_euclid_int_impl!(CheckedRemEuclid for i128);
#[cfg(has_i128)]
checked_rem_euclid_uint_impl!(CheckedRemEuclid for u128);
checked_euclid_uint_impl!(u128);
#[cfg(test)]
mod tests {
@@ -249,8 +213,8 @@ mod tests {
{
let x: $t = 10;
let y: $t = 3;
assert_eq!(DivEuclid::div_euclid(x,y),3);
assert_eq!(RemEuclid::rem_euclid(x,y),1);
assert_eq!(Euclid::div_euclid(x, y),3);
assert_eq!(Euclid::rem_euclid(x, y),1);
}
)+
};
@@ -267,13 +231,13 @@ mod tests {
{
let x: $t = 10;
let y: $t = -3;
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);
assert_eq!(Euclid::div_euclid(x, y),-3);
assert_eq!(Euclid::div_euclid(-x, y),4);
assert_eq!(Euclid::rem_euclid(x, y),1);
assert_eq!(Euclid::rem_euclid(-x, y),2);
let x: $t = $t::min_value()+1;
let y: $t = -1;
assert_eq!(DivEuclid::div_euclid(x,y),$t::max_value());
assert_eq!(Euclid::div_euclid(x, y),$t::max_value());
}
)+
};
@@ -283,7 +247,6 @@ mod tests {
}
#[test]
#[cfg(any(feature = "std", feature = "libm"))]
fn euclid_float() {
macro_rules! test_euclid {
($($t:ident)+) => {
@@ -291,14 +254,14 @@ mod tests {
{
let x: $t = 12.1;
let y: $t = 3.2;
assert!(DivEuclid::div_euclid(x,y)*y+RemEuclid::rem_euclid(x,y)-x
<=46.4 * <$t as ::Float>::epsilon());
assert!(DivEuclid::div_euclid(x,-y)*-y+RemEuclid::rem_euclid(x,-y)-x
<= 46.4 * <$t as ::Float>::epsilon());
assert!(DivEuclid::div_euclid(-x,y)*y+RemEuclid::rem_euclid(-x,y)-(-x)
<= 46.4 * <$t as ::Float>::epsilon());
assert!(DivEuclid::div_euclid(-x,-y)*-y+RemEuclid::rem_euclid(-x,-y)-(-x)
<= 46.4 * <$t as ::Float>::epsilon());
assert!(Euclid::div_euclid(x, y)*y+Euclid::rem_euclid(x, y)-x
<=46.4 * <$t as ::FloatCore>::epsilon());
assert!(Euclid::div_euclid(x, -y)*-y+Euclid::rem_euclid(x, -y)-x
<= 46.4 * <$t as ::FloatCore>::epsilon());
assert!(Euclid::div_euclid(-x, y)*y+Euclid::rem_euclid(-x, y)-(-x)
<= 46.4 * <$t as ::FloatCore>::epsilon());
assert!(Euclid::div_euclid(-x, -y)*-y+Euclid::rem_euclid(-x, -y)-(-x)
<= 46.4 * <$t as ::FloatCore>::epsilon());
}
)+
};
@@ -313,10 +276,10 @@ mod tests {
($($t:ident)+) => {
$(
{
assert_eq!(CheckedDivEuclid::checked_div_euclid($t::min_value(),-1),None);
assert_eq!(CheckedRemEuclid::checked_rem_euclid($t::min_value(),-1),None);
assert_eq!(CheckedDivEuclid::checked_div_euclid(1,0),None);
assert_eq!(CheckedRemEuclid::checked_rem_euclid(1,0),None);
assert_eq!(CheckedEuclid::checked_div_euclid($t::min_value(), -1),None);
assert_eq!(CheckedEuclid::checked_rem_euclid($t::min_value(), -1),None);
assert_eq!(CheckedEuclid::checked_div_euclid(1, 0),None);
assert_eq!(CheckedEuclid::checked_rem_euclid(1, 0),None);
}
)+
};