diff --git a/src/arith.rs b/src/arith.rs index 7b5ba24..44355fb 100644 --- a/src/arith.rs +++ b/src/arith.rs @@ -15,13 +15,12 @@ use core::cmp::Ordering; use core::iter::{Product, Sum}; -use core::mem; use core::ops::{ Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign, }; use frac::{IsLessOrEqual, True, Unsigned, U128, U16, U32, U64, U8}; -use sealed::SealedFixed; +use sealed::{SealedFixed, SealedInt}; use wide_div::WideDivRem; use { FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32, FixedU64, @@ -37,7 +36,7 @@ macro_rules! refs { type Output = $Fixed; #[inline] fn $method(self, rhs: $Fixed) -> $Fixed { - <$Fixed as $Imp<$Fixed>>::$method(*self, rhs) + (*self).$method(rhs) } } @@ -48,7 +47,7 @@ macro_rules! refs { type Output = $Fixed; #[inline] fn $method(self, rhs: &$Fixed) -> $Fixed { - <$Fixed as $Imp<$Fixed>>::$method(self, *rhs) + self.$method(*rhs) } } @@ -59,7 +58,7 @@ macro_rules! refs { type Output = $Fixed; #[inline] fn $method(self, rhs: &$Fixed) -> $Fixed { - <$Fixed as $Imp<$Fixed>>::$method(*self, *rhs) + (*self).$method(*rhs) } } }; @@ -73,7 +72,7 @@ macro_rules! refs_assign { { #[inline] fn $method(&mut self, rhs: &$Fixed) { - <$Fixed as $Imp<$Fixed>>::$method(self, *rhs); + self.$method(*rhs); } } }; @@ -88,10 +87,7 @@ macro_rules! pass { type Output = $Fixed; #[inline] fn $method(self, rhs: $Fixed) -> $Fixed { - $Fixed::from_bits(<$Inner as $Imp<$Inner>>::$method( - self.to_bits(), - rhs.to_bits(), - )) + Self::from_bits(self.to_bits().$method(rhs.to_bits())) } } @@ -107,7 +103,7 @@ macro_rules! pass_assign { { #[inline] fn $method(&mut self, rhs: $Fixed) { - <$Inner as $Imp<$Inner>>::$method(&mut (self.0).0, rhs.to_bits()); + (&mut (self.0).0).$method(rhs.to_bits()) } } @@ -124,7 +120,7 @@ macro_rules! pass_one { type Output = $Fixed; #[inline] fn $method(self) -> $Fixed { - $Fixed::from_bits(<$Inner as $Imp>::$method(self.to_bits())) + Self::from_bits(self.to_bits().$method()) } } @@ -135,7 +131,7 @@ macro_rules! pass_one { type Output = $Fixed; #[inline] fn $method(self) -> $Fixed { - <$Fixed as $Imp>::$method(*self) + (*self).$method() } } }; @@ -150,7 +146,7 @@ macro_rules! shift { type Output = $Fixed; #[inline] fn $method(self, rhs: $Rhs) -> $Fixed { - $Fixed::from_bits(<$Inner as $Imp<$Rhs>>::$method(self.to_bits(), rhs)) + $Fixed::from_bits(self.to_bits().$method(rhs)) } } @@ -161,7 +157,7 @@ macro_rules! shift { type Output = $Fixed; #[inline] fn $method(self, rhs: $Rhs) -> $Fixed { - <$Fixed as $Imp<$Rhs>>::$method(*self, rhs) + (*self).$method(rhs) } } @@ -172,7 +168,7 @@ macro_rules! shift { type Output = $Fixed; #[inline] fn $method(self, rhs: &$Rhs) -> $Fixed { - <$Fixed as $Imp<$Rhs>>::$method(self, *rhs) + self.$method(*rhs) } } @@ -183,7 +179,7 @@ macro_rules! shift { type Output = $Fixed; #[inline] fn $method(self, rhs: &$Rhs) -> $Fixed { - <$Fixed as $Imp<$Rhs>>::$method(*self, *rhs) + (*self).$method(*rhs) } } }; @@ -197,7 +193,7 @@ macro_rules! shift_assign { { #[inline] fn $method(&mut self, rhs: $Rhs) { - <$Inner as $Imp<$Rhs>>::$method(&mut (self.0).0, rhs); + (&mut (self.0).0).$method(rhs) } } @@ -207,7 +203,7 @@ macro_rules! shift_assign { { #[inline] fn $method(&mut self, rhs: &$Rhs) { - <$Fixed as $Imp<$Rhs>>::$method(self, *rhs); + self.$method(*rhs) } } }; @@ -242,9 +238,9 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn mul(self, rhs: $Fixed) -> $Fixed { - let (ans, dir) = self.to_bits().mul_dir(rhs.to_bits(), Frac::to_u32()); + let (ans, dir) = self.to_bits().mul_dir(rhs.to_bits(), Frac::U32); debug_assert!(dir == Ordering::Equal, "overflow"); - $Fixed::from_bits(ans) + Self::from_bits(ans) } } @@ -256,7 +252,7 @@ macro_rules! fixed_arith { { #[inline] fn mul_assign(&mut self, rhs: $Fixed) { - *self = <$Fixed as Mul<$Fixed>>::mul(*self, rhs) + *self = (*self).mul(rhs) } } @@ -269,9 +265,9 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn div(self, rhs: $Fixed) -> $Fixed { - let (ans, dir) = self.to_bits().div_dir(rhs.to_bits(), Frac::to_u32()); + let (ans, dir) = self.to_bits().div_dir(rhs.to_bits(), Frac::U32); debug_assert!(dir == Ordering::Equal, "overflow"); - $Fixed::from_bits(ans) + Self::from_bits(ans) } } @@ -283,7 +279,7 @@ macro_rules! fixed_arith { { #[inline] fn div_assign(&mut self, rhs: $Fixed) { - *self = <$Fixed as Div<$Fixed>>::div(*self, rhs) + *self = (*self).div(rhs) } } @@ -304,7 +300,7 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn mul(self, rhs: $Inner) -> $Fixed { - $Fixed::from_bits(self.to_bits() * rhs) + Self::from_bits(self.to_bits().mul(rhs)) } } @@ -315,7 +311,7 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn mul(self, rhs: $Fixed) -> $Fixed { - <$Fixed as Mul<$Inner>>::mul(rhs, self) + rhs.mul(self) } } @@ -326,7 +322,7 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn mul(self, rhs: $Inner) -> $Fixed { - <$Fixed as Mul<$Inner>>::mul(*self, rhs) + (*self).mul(rhs) } } @@ -337,7 +333,7 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn mul(self, rhs: &$Fixed) -> $Fixed { - <$Fixed as Mul<$Inner>>::mul(*rhs, self) + (*rhs).mul(self) } } @@ -348,7 +344,7 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn mul(self, rhs: &$Inner) -> $Fixed { - <$Fixed as Mul<$Inner>>::mul(self, *rhs) + self.mul(*rhs) } } @@ -359,7 +355,7 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn mul(self, rhs: $Fixed) -> $Fixed { - <$Fixed as Mul<$Inner>>::mul(rhs, *self) + rhs.mul(*self) } } @@ -370,7 +366,7 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn mul(self, rhs: &$Inner) -> $Fixed { - <$Fixed as Mul<$Inner>>::mul(*self, *rhs) + (*self).mul(*rhs) } } @@ -381,7 +377,7 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn mul(self, rhs: &$Fixed) -> $Fixed { - <$Fixed as Mul<$Inner>>::mul(*rhs, *self) + (*rhs).mul(*self) } } @@ -391,7 +387,7 @@ macro_rules! fixed_arith { { #[inline] fn mul_assign(&mut self, rhs: $Inner) { - *self = <$Fixed as Mul<$Inner>>::mul(*self, rhs) + *self = (*self).mul(rhs); } } @@ -401,7 +397,7 @@ macro_rules! fixed_arith { { #[inline] fn mul_assign(&mut self, rhs: &$Inner) { - *self = <$Fixed as Mul<$Inner>>::mul(*self, *rhs) + *self = (*self).mul(*rhs); } } @@ -412,7 +408,7 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn div(self, rhs: $Inner) -> $Fixed { - $Fixed::from_bits(self.to_bits() / rhs) + Self::from_bits(self.to_bits().div(rhs)) } } @@ -423,7 +419,7 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn div(self, rhs: $Inner) -> $Fixed { - <$Fixed as Div<$Inner>>::div(*self, rhs) + (*self).div(rhs) } } @@ -434,7 +430,7 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn div(self, rhs: &$Inner) -> $Fixed { - <$Fixed as Div<$Inner>>::div(self, *rhs) + self.div(*rhs) } } impl<'a, 'b, Frac> Div<&'a $Inner> for &'b $Fixed @@ -444,7 +440,7 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn div(self, rhs: &$Inner) -> $Fixed { - <$Fixed as Div<$Inner>>::div(*self, *rhs) + (*self).div(*rhs) } } @@ -454,7 +450,7 @@ macro_rules! fixed_arith { { #[inline] fn div_assign(&mut self, rhs: $Inner) { - *self = <$Fixed as Div<$Inner>>::div(*self, rhs) + *self = (*self).div(rhs); } } @@ -464,7 +460,7 @@ macro_rules! fixed_arith { { #[inline] fn div_assign(&mut self, rhs: &$Inner) { - *self = <$Fixed as Div<$Inner>>::div(*self, *rhs) + *self = (*self).div(*rhs); } } @@ -475,7 +471,7 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn rem(self, rhs: $Inner) -> $Fixed { - $Fixed::from_bits(self.to_bits() % rhs) + Self::from_bits(self.to_bits().rem(rhs)) } } @@ -486,7 +482,7 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn rem(self, rhs: $Inner) -> $Fixed { - <$Fixed as Rem<$Inner>>::rem(*self, rhs) + (*self).rem(rhs) } } @@ -497,7 +493,7 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn rem(self, rhs: &$Inner) -> $Fixed { - <$Fixed as Rem<$Inner>>::rem(self, *rhs) + self.rem(*rhs) } } @@ -508,7 +504,7 @@ macro_rules! fixed_arith { type Output = $Fixed; #[inline] fn rem(self, rhs: &$Inner) -> $Fixed { - <$Fixed as Rem<$Inner>>::rem(*self, *rhs) + (*self).rem(*rhs) } } @@ -518,7 +514,7 @@ macro_rules! fixed_arith { { #[inline] fn rem_assign(&mut self, rhs: $Inner) { - *self = <$Fixed as Rem<$Inner>>::rem(*self, rhs) + *self = (*self).rem(rhs); } } @@ -528,7 +524,7 @@ macro_rules! fixed_arith { { #[inline] fn rem_assign(&mut self, rhs: &$Inner) { - *self = <$Fixed as Rem<$Inner>>::rem(*self, *rhs) + *self = (*self).rem(*rhs); } } @@ -552,7 +548,7 @@ macro_rules! fixed_arith { Frac: Unsigned + IsLessOrEqual<$Len, Output = True>, { fn sum>>(iter: I) -> $Fixed { - iter.fold($Fixed::from_bits(0), Add::add) + iter.fold(Self::from_bits(0), Add::add) } } @@ -561,7 +557,7 @@ macro_rules! fixed_arith { Frac: 'a + Unsigned + IsLessOrEqual<$Len, Output = True>, { fn sum>>(iter: I) -> $Fixed { - iter.fold($Fixed::from_bits(0), Add::add) + iter.fold(Self::from_bits(0), Add::add) } } @@ -571,7 +567,7 @@ macro_rules! fixed_arith { { fn product>>(mut iter: I) -> $Fixed { match iter.next() { - None => <$Fixed as SealedFixed>::one().expect("overflow"), + None => Self::one().expect("overflow"), Some(first) => iter.fold(first, Mul::mul), } } @@ -583,7 +579,7 @@ macro_rules! fixed_arith { { fn product>>(mut iter: I) -> $Fixed { match iter.next() { - None => <$Fixed as SealedFixed>::one().expect("overflow"), + None => Self::one().expect("overflow"), Some(first) => iter.fold(*first, Mul::mul), } } @@ -603,19 +599,19 @@ fixed_arith! { FixedI64(i64, U64, 64), Signed } fixed_arith! { FixedI128(i128, U128, 128), Signed } pub(crate) trait MulDivDir: Sized { - fn mul_dir(self, rhs: Self, frac_bits: u32) -> (Self, Ordering); - fn div_dir(self, rhs: Self, frac_bits: u32) -> (Self, Ordering); + fn mul_dir(self, rhs: Self, frac_nbits: u32) -> (Self, Ordering); + fn div_dir(self, rhs: Self, frac_nbits: u32) -> (Self, Ordering); } macro_rules! mul_div_widen { ($Single:ty, $Double:ty, $Signedness:tt) => { impl MulDivDir for $Single { #[inline] - fn mul_dir(self, rhs: $Single, frac_bits: u32) -> ($Single, Ordering) { - const BITS: u32 = mem::size_of::<$Single>() as u32 * 8; - let int_bits: u32 = BITS - frac_bits; - let lhs2 = <$Double as From<$Single>>::from(self); - let rhs2 = <$Double as From<$Single>>::from(rhs) << int_bits; + fn mul_dir(self, rhs: $Single, frac_nbits: u32) -> ($Single, Ordering) { + const NBITS: u32 = <$Single>::NBITS; + let int_nbits: u32 = NBITS - frac_nbits; + let lhs2 = <$Double>::from(self); + let rhs2 = <$Double>::from(rhs) << int_nbits; let (prod2, overflow) = lhs2.overflowing_mul(rhs2); let dir; if_unsigned! { @@ -636,16 +632,16 @@ macro_rules! mul_div_widen { Ordering::Greater }; } - ((prod2 >> BITS) as $Single, dir) + ((prod2 >> NBITS) as $Single, dir) } #[inline] - fn div_dir(self, rhs: $Single, frac_bits: u32) -> ($Single, Ordering) { - let lhs2 = <$Double as From<$Single>>::from(self) << frac_bits; - let rhs2 = <$Double as From<$Single>>::from(rhs); + fn div_dir(self, rhs: $Single, frac_nbits: u32) -> ($Single, Ordering) { + let lhs2 = <$Double>::from(self) << frac_nbits; + let rhs2 = <$Double>::from(rhs); let quot2 = lhs2 / rhs2; let quot = quot2 as $Single; - let dir = <$Double as From<$Single>>::from(quot).cmp("2); + let dir = <$Double>::from(quot).cmp("2); (quot, dir) } } @@ -754,28 +750,22 @@ impl FallbackHelper for i128 { macro_rules! mul_div_fallback { ($Single:ty, $Uns:ty, $Signedness:tt) => { impl MulDivDir for $Single { - fn mul_dir(self, rhs: $Single, frac_bits: u32) -> ($Single, Ordering) { - if frac_bits == 0 { + fn mul_dir(self, rhs: $Single, frac_nbits: u32) -> ($Single, Ordering) { + if frac_nbits == 0 { let (ans, overflow) = self.overflowing_mul(rhs); - let dir; - if_unsigned! { - $Signedness; - dir = if !overflow { - Ordering::Equal - } else { - Ordering::Less - }; - } - if_signed! { - $Signedness; - dir = if !overflow { - Ordering::Equal - } else if (self < 0) == (rhs < 0) { - Ordering::Less - } else { - Ordering::Greater - }; - } + let dir = if !overflow { + Ordering::Equal + } else { + if_signed_unsigned!( + $Signedness, + if (self < 0) == (rhs < 0) { + Ordering::Less + } else { + Ordering::Greater + }, + Ordering::Less, + ) + }; (ans, dir) } else { let (lh, ll) = self.hi_lo(); @@ -792,39 +782,33 @@ macro_rules! mul_div_fallback { let (col12_hi, col12_lo) = col12.hi_lo(); let ans01 = col12_lo.shift_lo_up_unsigned() + col01_lo; let ans23 = lh_rh + col12_hi + carry_col3.shift_lo_up(); - ans23.combine_lo_then_shl(ans01, frac_bits) + ans23.combine_lo_then_shl(ans01, frac_nbits) } } - fn div_dir(self, rhs: $Single, frac_bits: u32) -> ($Single, Ordering) { - if frac_bits == 0 { + fn div_dir(self, rhs: $Single, frac_nbits: u32) -> ($Single, Ordering) { + if frac_nbits == 0 { let (ans, overflow) = self.overflowing_div(rhs); - let dir; - if_unsigned! { - $Signedness; - dir = if !overflow { - Ordering::Equal - } else { - Ordering::Less - }; - } - if_signed! { - $Signedness; - dir = if !overflow { - Ordering::Equal - } else if (self < 0) == (rhs < 0) { - Ordering::Less - } else { - Ordering::Greater - }; - } + let dir = if !overflow { + Ordering::Equal + } else { + if_signed_unsigned!( + $Signedness, + if (self < 0) == (rhs < 0) { + Ordering::Less + } else { + Ordering::Greater + }, + Ordering::Less, + ) + }; (ans, dir) } else { - const BITS: u32 = mem::size_of::<$Single>() as u32 * 8; - let lhs2 = (self >> (BITS - frac_bits), (self << frac_bits) as $Uns); + const NBITS: u32 = <$Single>::NBITS; + let lhs2 = (self >> (NBITS - frac_nbits), (self << frac_nbits) as $Uns); let (quot2, _) = rhs.div_rem_from(lhs2); let quot = quot2.1 as $Single; - let quot2_ret = (quot >> (BITS / 2) >> (BITS / 2), quot2.1); + let quot2_ret = (quot >> (NBITS / 2) >> (NBITS - NBITS / 2), quot2.1); let dir = (quot2_ret.0) .cmp("2.0) .then((quot2_ret.1).cmp("2.1)); @@ -853,11 +837,11 @@ mod tests { #[test] fn fixed_u16() { use frac::U7 as Frac; - let frac = Frac::to_u32(); + let frac = Frac::U32; let a = 12; let b = 4; - let af = FixedU16::::from_bits(a << Frac::to_u32()); - let bf = FixedU16::::from_bits(b << Frac::to_u32()); + let af = FixedU16::::from_bits(a << Frac::U32); + let bf = FixedU16::::from_bits(b << Frac::U32); assert_eq!((af + bf).to_bits(), (a << frac) + (b << frac)); assert_eq!((af - bf).to_bits(), (a << frac) - (b << frac)); assert_eq!((af * bf).to_bits(), (a << frac) * b); @@ -873,7 +857,7 @@ mod tests { #[test] fn fixed_i16() { use frac::U7 as Frac; - let frac = Frac::to_u32(); + let frac = Frac::U32; let a = 12; let b = 4; for &pair in &[(a, b), (a, -b), (-a, b), (-a, -b)] { @@ -897,7 +881,7 @@ mod tests { #[test] fn fixed_u128() { use frac::U7 as Frac; - let frac = Frac::to_u32(); + let frac = Frac::U32; let a = 0x0003_4567_89ab_cdef_0123_4567_89ab_cdef_u128; let b = 5; for &(a, b) in &[(a, b), (b, a)] { @@ -919,7 +903,7 @@ mod tests { #[test] fn fixed_i128() { use frac::U7 as Frac; - let frac = Frac::to_u32(); + let frac = Frac::U32; let a = 0x0003_4567_89ab_cdef_0123_4567_89ab_cdef_i128; let b = 5; for &(a, b) in &[ diff --git a/src/cmp.rs b/src/cmp.rs index ccff19f..6c574be 100644 --- a/src/cmp.rs +++ b/src/cmp.rs @@ -14,7 +14,7 @@ // . use core::cmp::Ordering; -use frac::{self, IsLessOrEqual, True, Unsigned, U128, U16, U32, U64, U8}; +use frac::{IsLessOrEqual, True, Unsigned, U0, U128, U16, U32, U64, U8}; use { FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32, FixedU64, FixedU8, @@ -31,7 +31,7 @@ macro_rules! fixed_cmp { { #[inline] fn eq(&self, rhs: &$Fixed) -> bool { - let (fl, fr) = (Frac::to_u32(), FracRhs::to_u32()); + let (fl, fr) = (Frac::U32, FracRhs::U32); if fl == fr { self.to_bits() == rhs.to_bits() } else if fl < fr { @@ -56,7 +56,7 @@ macro_rules! fixed_cmp { { #[inline] fn eq(&self, rhs: &$Inner) -> bool { - <$Fixed as PartialEq<$Fixed>>::eq(self, &$Fixed::from_bits(*rhs)) + self.eq(&$Fixed::::from_bits(*rhs)) } } @@ -66,7 +66,7 @@ macro_rules! fixed_cmp { { #[inline] fn eq(&self, rhs: &$Fixed) -> bool { - <$Fixed as PartialEq<$Fixed>>::eq(&$Fixed::from_bits(*self), rhs) + $Fixed::::from_bits(*self).eq(rhs) } } @@ -87,7 +87,7 @@ macro_rules! fixed_cmp { { #[inline] fn partial_cmp(&self, rhs: &$Fixed) -> Option { - let (fl, fr) = (Frac::to_u32(), FracRhs::to_u32()); + let (fl, fr) = (Frac::U32, FracRhs::U32); if fl == fr { self.to_bits().partial_cmp(&rhs.to_bits()) } else if fl < fr { @@ -112,7 +112,7 @@ macro_rules! fixed_cmp { #[inline] fn lt(&self, rhs: &$Fixed) -> bool { - let (fl, fr) = (Frac::to_u32(), FracRhs::to_u32()); + let (fl, fr) = (Frac::U32, FracRhs::U32); if fl == fr { self.to_bits() < rhs.to_bits() } else if fl < fr { @@ -134,7 +134,7 @@ macro_rules! fixed_cmp { #[inline] fn le(&self, rhs: &$Fixed) -> bool { - let (fl, fr) = (Frac::to_u32(), FracRhs::to_u32()); + let (fl, fr) = (Frac::U32, FracRhs::U32); if fl == fr { self.to_bits() <= rhs.to_bits() } else if fl < fr { @@ -170,27 +170,27 @@ macro_rules! fixed_cmp { { #[inline] fn partial_cmp(&self, rhs: &$Inner) -> Option { - self.partial_cmp(&$Fixed::::from_bits(*rhs)) + self.partial_cmp(&$Fixed::::from_bits(*rhs)) } #[inline] fn lt(&self, rhs: &$Inner) -> bool { - self.lt(&$Fixed::::from_bits(*rhs)) + self.lt(&$Fixed::::from_bits(*rhs)) } #[inline] fn le(&self, rhs: &$Inner) -> bool { - self.le(&$Fixed::::from_bits(*rhs)) + self.le(&$Fixed::::from_bits(*rhs)) } #[inline] fn gt(&self, rhs: &$Inner) -> bool { - self.gt(&$Fixed::::from_bits(*rhs)) + self.gt(&$Fixed::::from_bits(*rhs)) } #[inline] fn ge(&self, rhs: &$Inner) -> bool { - self.ge(&$Fixed::::from_bits(*rhs)) + self.ge(&$Fixed::::from_bits(*rhs)) } } @@ -200,27 +200,27 @@ macro_rules! fixed_cmp { { #[inline] fn partial_cmp(&self, rhs: &$Fixed) -> Option { - $Fixed::::from_bits(*self).partial_cmp(rhs) + $Fixed::::from_bits(*self).partial_cmp(rhs) } #[inline] fn lt(&self, rhs: &$Fixed) -> bool { - $Fixed::::from_bits(*self).lt(rhs) + $Fixed::::from_bits(*self).lt(rhs) } #[inline] fn le(&self, rhs: &$Fixed) -> bool { - $Fixed::::from_bits(*self).le(rhs) + $Fixed::::from_bits(*self).le(rhs) } #[inline] fn gt(&self, rhs: &$Fixed) -> bool { - $Fixed::::from_bits(*self).gt(rhs) + $Fixed::::from_bits(*self).gt(rhs) } #[inline] fn ge(&self, rhs: &$Fixed) -> bool { - $Fixed::::from_bits(*self).ge(rhs) + $Fixed::::from_bits(*self).ge(rhs) } } }; diff --git a/src/convert.rs b/src/convert.rs index 619c456..35164aa 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -39,7 +39,7 @@ macro_rules! convert { #[inline] fn from(src: $SrcU) -> $DstU { let unshifted = $DstU::::from_bits(src.to_bits().into()).to_bits(); - let shift = FracDst::to_u32() - FracSrc::to_u32(); + let shift = FracDst::U32 - FracSrc::U32; $DstU::::from_bits(unshifted << shift) } } @@ -59,7 +59,7 @@ macro_rules! convert { #[inline] fn from(src: $SrcI) -> $DstI { let unshifted = $DstI::::from_bits(src.to_bits().into()).to_bits(); - let shift = FracDst::to_u32() - FracSrc::to_u32(); + let shift = FracDst::U32 - FracSrc::U32; $DstI::::from_bits(unshifted << shift) } } @@ -82,7 +82,7 @@ macro_rules! convert { #[inline] fn from(src: $SrcU) -> $DstI { let unshifted = $DstI::::from_bits(src.to_bits().into()).to_bits(); - let shift = FracDst::to_u32() - FracSrc::to_u32(); + let shift = FracDst::U32 - FracSrc::U32; $DstI::::from_bits(unshifted << shift) } } @@ -115,7 +115,7 @@ macro_rules! prim_to_fixed { #[inline] fn from(src: $SrcU) -> $DstU { let unshifted = $DstU::::from_bits(src.into()).to_bits(); - let shift = FracDst::to_u32(); + let shift = FracDst::U32; $DstU::::from_bits(unshifted << shift) } } @@ -130,7 +130,7 @@ macro_rules! prim_to_fixed { #[inline] fn from(src: $SrcI) -> $DstI { let unshifted = $DstI::::from_bits(src.into()).to_bits(); - let shift = FracDst::to_u32(); + let shift = FracDst::U32; $DstI::::from_bits(unshifted << shift) } } @@ -148,7 +148,7 @@ macro_rules! prim_to_fixed { #[inline] fn from(src: $SrcU) -> $DstI { let unshifted = $DstI::::from_bits(src.into()).to_bits(); - let shift = FracDst::to_u32(); + let shift = FracDst::U32; $DstI::::from_bits(unshifted << shift) } } @@ -203,7 +203,7 @@ macro_rules! bool_to_fixed { #[inline] fn from(src: bool) -> $DstU { let unshifted = $DstU::::from_bits(src.into()).to_bits(); - let shift = FracDst::to_u32(); + let shift = FracDst::U32; $DstU::::from_bits(unshifted << shift) } } @@ -218,7 +218,7 @@ macro_rules! bool_to_fixed { #[inline] fn from(src: bool) -> $DstI { let unshifted = $DstI::::from_bits(src.into()).to_bits(); - let shift = FracDst::to_u32(); + let shift = FracDst::U32; $DstI::::from_bits(unshifted << shift) } } diff --git a/src/display.rs b/src/display.rs index add616d..73de60f 100644 --- a/src/display.rs +++ b/src/display.rs @@ -82,7 +82,7 @@ macro_rules! fmt_radix2_helper { #[inline] fn take_frac_digit(&mut self, digit_bits: u32) -> u8 { - let nbits = <$UInner as SealedInt>::NBITS; + let nbits = <$UInner>::NBITS; let rem_bits = nbits - digit_bits; let mask = !0 << rem_bits; let ret = ((*self & mask) >> rem_bits) as u8; @@ -252,7 +252,7 @@ macro_rules! fmt_dec_helper { impl FmtDecHelper for $UInner { #[inline] fn cmp_half(&self) -> Ordering { - self.cmp(&<$UInner as SealedInt>::MSB) + self.cmp(&<$UInner>::MSB) } #[inline] @@ -442,7 +442,7 @@ mod tests { #[test] fn hex() { use frac::U7 as Frac; - let frac = Frac::to_u32(); + let frac = Frac::U32; for i in 0..(1 << frac) { let p = 0x1234_5678_9abc_def0u64 ^ i as u64; let n = -0x1234_5678_9abc_def0i64 ^ i64::from(i); @@ -459,7 +459,7 @@ mod tests { #[test] fn dec() { use frac::U7 as Frac; - let frac = Frac::to_u32(); + let frac = Frac::U32; for i in 0..(1 << frac) { let bits = !0u32 ^ i; let flt = f64::from(bits) / f64::from(frac).exp2(); diff --git a/src/lib.rs b/src/lib.rs index 04c5e04..03e2cff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -265,14 +265,14 @@ macro_rules! pass_method { #[doc = $comment] #[inline] pub fn $method() -> $Fixed { - $Fixed::from_bits(<$Inner>::$method()) + Self::from_bits(<$Inner>::$method()) } }; ($comment:expr, $Fixed:ident($Inner:ty) => fn $method:ident(self)) => { #[doc = $comment] #[inline] pub fn $method(self) -> $Fixed { - $Fixed::from_bits(<$Inner>::$method(self.to_bits())) + Self::from_bits(<$Inner>::$method(self.to_bits())) } }; ($comment:expr, $Fixed:ident($Inner:ty) => fn $method:ident(self) -> $ret_ty:ty) => { @@ -289,7 +289,7 @@ macro_rules! pass_method { #[doc = $comment] #[inline] pub fn $method(self, $param: $param_ty) -> $Fixed { - $Fixed::from_bits(<$Inner>::$method(self.to_bits(), $param)) + Self::from_bits(<$Inner>::$method(self.to_bits(), $param)) } }; } @@ -318,7 +318,7 @@ This method has been replaced by [`checked_from_float`]. #[deprecated(since = "0.2.0", note = "replaced by checked_from_float")] #[inline] pub fn $method(val: $Float) -> Option<$Fixed<$Frac>> { - <$Fixed<$Frac>>::checked_from_float(val) + Self::checked_from_float(val) } ); }; @@ -392,7 +392,7 @@ assert_eq!(five_half.to_string(), \"5.5\"); { #[inline] fn clone(&self) -> $Fixed { - $Fixed::from_bits(self.to_bits()) + Self::from_bits(self.to_bits()) } } @@ -407,7 +407,7 @@ assert_eq!(five_half.to_string(), \"5.5\"); { #[inline] fn default() -> $Fixed { - $Fixed::from_bits(<$Inner as Default>::default()) + Self::from_bits(<$Inner>::default()) } } @@ -487,7 +487,7 @@ assert_eq!(Fix::int_bits(), ", ), #[inline] pub fn int_bits() -> u32 { - ::INT_NBITS + Self::INT_NBITS } ); @@ -509,7 +509,7 @@ assert_eq!(Fix::frac_bits(), 6); ), #[inline] pub fn frac_bits() -> u32 { - ::FRAC_NBITS + Self::FRAC_NBITS } ); @@ -614,7 +614,7 @@ assert_eq!(Fix::from_fixed(src >> 4), Fix::from_bits(1)); where F: Fixed, { - let (wrapped, overflow) = $Fixed::overflowing_from_fixed(val); + let (wrapped, overflow) = Self::overflowing_from_fixed(val); #[cfg(debug_assertions)] { if overflow { @@ -675,7 +675,7 @@ assert!(Fix::checked_from_fixed(too_small).is_none()); where F: Fixed, { - let (wrapped, overflow) = $Fixed::overflowing_from_fixed(val); + let (wrapped, overflow) = Self::overflowing_from_fixed(val); if overflow { None } else { Some(wrapped) } } ); @@ -730,34 +730,33 @@ assert_eq!(Fix::saturating_from_fixed(too_small), Fix::min_value()); where F: Fixed, { - let (value, overflow) = - <::Bits as SealedInt>::to_fixed_overflow( - val.to_bits(), - F::FRAC_NBITS, - <$Fixed>::FRAC_NBITS, - <$Fixed>::FRAC_NBITS, - ); + let (value, overflow) = F::Bits::to_fixed_overflow( + val.to_bits(), + F::FRAC_NBITS, + Self::FRAC_NBITS, + Self::FRAC_NBITS, + ); if overflow { - return if val.to_bits().neg_abs().0 { - $Fixed::min_value() + return if val.to_bits().is_negative() { + Self::min_value() } else { - $Fixed::max_value() + Self::max_value() }; } let bits = if_signed_unsigned!( $Signedness, match value { Widest::Unsigned(bits) => { - if (bits as <$Fixed as SealedFixed>::Bits) < 0 { - return $Fixed::max_value(); + if (bits as ::Bits) < 0 { + return Self::max_value(); } - bits as _ + bits as ::Bits } - Widest::Negative(bits) => bits as _, + Widest::Negative(bits) => bits as ::Bits, }, match value { - Widest::Unsigned(bits) => bits as _, - Widest::Negative(_) => return $Fixed::min_value(), + Widest::Unsigned(bits) => bits as ::Bits, + Widest::Negative(_) => return Self::min_value(), }, ); SealedFixed::from_bits(bits) @@ -814,7 +813,7 @@ assert_eq!(Fix::wrapping_from_fixed(large), wrapped); where F: Fixed, { - $Fixed::overflowing_from_fixed(val).0 + Self::overflowing_from_fixed(val).0 } ); @@ -867,29 +866,28 @@ assert_eq!(Fix::overflowing_from_fixed(large), (wrapped, true)); where F: Fixed, { - let (value, mut overflow) = - <::Bits as SealedInt>::to_fixed_overflow( - val.to_bits(), - F::FRAC_NBITS, - <$Fixed>::FRAC_NBITS, - <$Fixed>::INT_NBITS, - ); + let (value, mut overflow) = F::Bits::to_fixed_overflow( + val.to_bits(), + F::FRAC_NBITS, + Self::FRAC_NBITS, + Self::INT_NBITS, + ); let bits = if_signed_unsigned!( $Signedness, match value { Widest::Unsigned(bits) => { - if (bits as <$Fixed as SealedFixed>::Bits) < 0 { + if (bits as ::Bits) < 0 { overflow = true; } - bits as _ + bits as ::Bits } - Widest::Negative(bits) => bits as _, + Widest::Negative(bits) => bits as ::Bits, }, match value { - Widest::Unsigned(bits) => bits as _, + Widest::Unsigned(bits) => bits as ::Bits, Widest::Negative(bits) => { overflow = true; - bits as _ + bits as ::Bits } }, ); @@ -1009,7 +1007,7 @@ assert_eq!(Fix::from_int(-3), Fix::from_bits(-3 << 4));", where I: Int, { - let (wrapped, overflow) = $Fixed::overflowing_from_int(val); + let (wrapped, overflow) = Self::overflowing_from_int(val); #[cfg(debug_assertions)] { if overflow { @@ -1079,7 +1077,7 @@ assert!(Fix::checked_from_int(too_small).is_none()); where I: Int, { - let (wrapped, overflow) = $Fixed::overflowing_from_int(val); + let (wrapped, overflow) = Self::overflowing_from_int(val); if overflow { None } else { Some(wrapped) } } ); @@ -1139,33 +1137,33 @@ assert_eq!(Fix::saturating_from_int(too_small), Fix::min_value()); where I: Int, { - let (value, overflow) = ::to_fixed_overflow( + let (value, overflow) = I::to_fixed_overflow( val, 0, - <$Fixed>::FRAC_NBITS, - <$Fixed>::INT_NBITS, + Self::FRAC_NBITS, + Self::INT_NBITS, ); if overflow { - return if val.neg_abs().0 { - $Fixed::min_value() + return if val.is_negative() { + Self::min_value() } else { - $Fixed::max_value() + Self::max_value() }; } let bits = if_signed_unsigned!( $Signedness, match value { Widest::Unsigned(bits) => { - if (bits as <$Fixed as SealedFixed>::Bits) < 0 { - return $Fixed::max_value(); + if (bits as ::Bits) < 0 { + return Self::max_value(); } - bits as _ + bits as ::Bits } - Widest::Negative(bits) => bits as _, + Widest::Negative(bits) => bits as ::Bits, }, match value { - Widest::Unsigned(bits) => bits as _, - Widest::Negative(_) => return $Fixed::min_value(), + Widest::Unsigned(bits) => bits as ::Bits, + Widest::Negative(_) => return Self::min_value(), }, ); SealedFixed::from_bits(bits) @@ -1226,7 +1224,7 @@ assert_eq!(Fix::wrapping_from_int(large), wrapped); where I: Int, { - $Fixed::overflowing_from_int(val).0 + Self::overflowing_from_int(val).0 } ); @@ -1288,28 +1286,28 @@ assert_eq!(Fix::overflowing_from_int(large), (wrapped, true)); where I: Int, { - let (value, mut overflow) = ::to_fixed_overflow( + let (value, mut overflow) = I::to_fixed_overflow( val, 0, - <$Fixed>::FRAC_NBITS, - <$Fixed>::INT_NBITS, + Self::FRAC_NBITS, + Self::INT_NBITS, ); let bits = if_signed_unsigned!( $Signedness, match value { Widest::Unsigned(bits) => { - if (bits as <$Fixed as SealedFixed>::Bits) < 0 { + if (bits as ::Bits) < 0 { overflow = true; } - bits as _ + bits as ::Bits } - Widest::Negative(bits) => bits as _, + Widest::Negative(bits) => bits as ::Bits, }, match value { - Widest::Unsigned(bits) => bits as _, + Widest::Unsigned(bits) => bits as ::Bits, Widest::Negative(bits) => { overflow = true; - bits as _ + bits as ::Bits } }, ); @@ -1355,11 +1353,7 @@ assert_eq!((-two_half).to_int(), -3);", #[inline] pub fn to_int(self) -> $Inner { let int = self.int().to_bits(); - if <$Fixed>::FRAC_NBITS < $nbits { - int >> <$Fixed>::FRAC_NBITS - } else { - int - } + if Self::INT_NBITS > 0 { int >> Self::FRAC_NBITS } else { int } } ); @@ -1417,7 +1411,7 @@ assert_eq!(Fix::from_float(1e-10), Fix::from_bits(0)); where F: Float, { - let (wrapped, overflow) = $Fixed::overflowing_from_float(val); + let (wrapped, overflow) = Self::overflowing_from_float(val); #[cfg(debug_assertions)] { if overflow { @@ -1482,12 +1476,8 @@ assert!(Fix::checked_from_float(f64::NAN).is_none()); if !val.is_finite() { return None; } - let (wrapped, overflow) = $Fixed::overflowing_from_float(val); - if overflow { - None - } else { - Some(wrapped) - } + let (wrapped, overflow) = Self::overflowing_from_float(val); + if overflow { None } else { Some(wrapped) } } ); @@ -1544,30 +1534,31 @@ assert_eq!(Fix::saturating_from_float(f64::NEG_INFINITY), Fix::min_value()); where F: Float, { + if val.is_nan() { + panic!("NaN"); + } let saturated = if val.is_sign_positive() { - $Fixed::max_value() + Self::max_value() } else { - $Fixed::min_value() + Self::min_value() }; if !val.is_finite() { return saturated; } - let (neg, abs_128, overflow) = ::to_fixed_neg_abs_overflow( + let (neg, abs_128, overflow) = F::to_fixed_neg_abs_overflow( val, - <$Fixed>::FRAC_NBITS, - <$Fixed>::INT_NBITS, + Self::FRAC_NBITS, + Self::INT_NBITS, ); if overflow { return saturated; } - let abs_bits = - abs_128 as <<$Fixed as SealedFixed>::Bits as SealedInt>::Unsigned; + let abs_bits = abs_128 as <::Bits as SealedInt>::Unsigned; - if <<$Fixed as SealedFixed>::Bits as SealedInt>::IS_SIGNED { + if ::Bits::IS_SIGNED { // most significant bit (msb) can be one only for min value, // that is for a negative value with only the msb true. - let msb = - <<$Fixed as SealedFixed>::Bits as SealedInt>::Unsigned::MSB; + let msb = <::Bits as SealedInt>::Unsigned::MSB; if abs_bits & msb != 0 { if !neg || abs_bits != msb { return saturated; @@ -1580,8 +1571,7 @@ assert_eq!(Fix::saturating_from_float(f64::NEG_INFINITY), Fix::min_value()); abs_bits.wrapping_neg() } else { abs_bits - } as <$Fixed as SealedFixed>::Bits; - + } as ::Bits; SealedFixed::from_bits(bits) } ); @@ -1642,7 +1632,7 @@ assert_eq!(Fix::wrapping_from_float(large), wrapped); where F: Float, { - $Fixed::overflowing_from_float(val).0 + Self::overflowing_from_float(val).0 } ); @@ -1710,20 +1700,17 @@ assert_eq!(Fix::overflowing_from_float(large), (wrapped, true)); if !val.is_finite() { panic!("{} is not finite", val); } - let (neg, abs_128, mut overflow) = - ::to_fixed_neg_abs_overflow( - val, - <$Fixed>::FRAC_NBITS, - <$Fixed>::INT_NBITS, - ); - let abs_bits = - abs_128 as <<$Fixed as SealedFixed>::Bits as SealedInt>::Unsigned; + let (neg, abs_128, mut overflow) = F::to_fixed_neg_abs_overflow( + val, + Self::FRAC_NBITS, + Self::INT_NBITS, + ); + let abs_bits = abs_128 as <::Bits as SealedInt>::Unsigned; - if <<$Fixed as SealedFixed>::Bits as SealedInt>::IS_SIGNED { + if ::Bits::IS_SIGNED { // most significant bit (msb) can be one only for min value, // that is for a negative value with only the msb true. - let msb = - <<$Fixed as SealedFixed>::Bits as SealedInt>::Unsigned::MSB; + let msb = <::Bits as SealedInt>::Unsigned::MSB; if abs_bits & msb != 0 { if !neg || abs_bits != msb { overflow = true; @@ -1736,7 +1723,7 @@ assert_eq!(Fix::overflowing_from_float(large), (wrapped, true)); abs_bits.wrapping_neg() } else { abs_bits - } as <$Fixed as SealedFixed>::Bits; + } as ::Bits; (SealedFixed::from_bits(bits), overflow) } @@ -1784,8 +1771,8 @@ assert_eq!(Fix::from_bits(", SealedFloat::from_neg_abs( neg, u128::from(abs), - <$Fixed>::FRAC_NBITS, - <$Fixed>::INT_NBITS, + Self::FRAC_NBITS, + Self::INT_NBITS, ) } ); @@ -1836,7 +1823,8 @@ assert_eq!((-two_and_quarter).int(), -three);", ), #[inline] pub fn int(self) -> $Fixed { - $Fixed::from_bits(self.to_bits() & Self::int_mask()) + let mask = Self::INT_MASK as ::Bits; + Self::from_bits(self.to_bits() & mask) } ); @@ -1886,7 +1874,8 @@ assert_eq!((-two_and_quarter).frac(), three_quarters);", ), #[inline] pub fn frac(self) -> $Fixed { - $Fixed::from_bits(self.to_bits() & Self::frac_mask()) + let mask = Self::FRAC_MASK as ::Bits; + Self::from_bits(self.to_bits() & mask) } ); @@ -2192,9 +2181,8 @@ assert_eq!(Fix::max_value().saturating_ceil(), Fix::max_value()); ), #[inline] pub fn saturating_ceil(self) -> $Fixed { - let saturated = $Fixed::max_value(); let (ceil, overflow) = self.overflowing_ceil(); - if overflow { saturated } else { ceil } + if overflow { Self::max_value() } else { ceil } } ); @@ -2239,9 +2227,8 @@ assert_eq!(AllFrac::min_value().saturating_floor(), AllFrac::min_value());", ), #[inline] pub fn saturating_floor(self) -> $Fixed { - let saturated = $Fixed::min_value(); let (floor, overflow) = self.overflowing_floor(); - if overflow { saturated } else { floor } + if overflow { Self::min_value() } else { floor } } ); @@ -2424,7 +2411,8 @@ assert_eq!(Fix::max_value().overflowing_ceil(), (Fix::min_value(), true)); if Self::int_bits() == 0 { return (int, self.to_bits() > 0); } - let increment = Self::from_bits(::lowest_int_bit()); + let int_lsb = Self::INT_LSB as ::Bits; + let increment = Self::from_bits(int_lsb); if_signed! { $Signedness; if Self::int_bits() == 1 { @@ -2520,14 +2508,15 @@ assert_eq!(Fix::max_value().overflowing_round(), (Fix::min_value(), true)); #[inline] pub fn overflowing_round(self) -> ($Fixed, bool) { let int = self.int(); - let highest_frac_bit = ::highest_frac_bit(); - if (self.to_bits() & highest_frac_bit) == 0 { + let frac_msb = Self::FRAC_MSB as ::Bits; + if (self.to_bits() & frac_msb) == 0 { return (int, false); } - let increment = Self::from_bits(::lowest_int_bit()); + let int_lsb = Self::INT_LSB as ::Bits; + let increment = Self::from_bits(int_lsb); if_signed! { $Signedness; - let tie = self.frac().to_bits() == highest_frac_bit; + let tie = self.frac().to_bits() == frac_msb; if Self::int_bits() == 0 { // if num is .100...00 = -0.5, we have overflow // otherwise .100...01, 0 < x < -0.5, no overflow @@ -2685,27 +2674,27 @@ assert_eq!(Fix::from_bits(bits).rotate_right(3), Fix::from_bits(rot)); /// Checked negation. #[inline] pub fn checked_neg(self) -> Option<$Fixed> { - <$Inner>::checked_neg(self.to_bits()).map($Fixed::from_bits) + <$Inner>::checked_neg(self.to_bits()).map(Self::from_bits) } /// Checked fixed-point addition. #[inline] pub fn checked_add(self, rhs: $Fixed) -> Option<$Fixed> { - <$Inner>::checked_add(self.to_bits(), rhs.to_bits()).map($Fixed::from_bits) + <$Inner>::checked_add(self.to_bits(), rhs.to_bits()).map(Self::from_bits) } /// Checked fixed-point subtraction. #[inline] pub fn checked_sub(self, rhs: $Fixed) -> Option<$Fixed> { - <$Inner>::checked_sub(self.to_bits(), rhs.to_bits()).map($Fixed::from_bits) + <$Inner>::checked_sub(self.to_bits(), rhs.to_bits()).map(Self::from_bits) } /// Checked fixed-point multiplication. #[inline] pub fn checked_mul(self, rhs: $Fixed) -> Option<$Fixed> { - let (ans, dir) = self.to_bits().mul_dir(rhs.to_bits(), Frac::to_u32()); + let (ans, dir) = self.to_bits().mul_dir(rhs.to_bits(), Frac::U32); match dir { - Ordering::Equal => Some($Fixed::from_bits(ans)), + Ordering::Equal => Some(Self::from_bits(ans)), _ => None, } } @@ -2716,9 +2705,9 @@ assert_eq!(Fix::from_bits(bits).rotate_right(3), Fix::from_bits(rot)); if rhs.to_bits() == 0 { return None; } - let (ans, dir) = self.to_bits().div_dir(rhs.to_bits(), Frac::to_u32()); + let (ans, dir) = self.to_bits().div_dir(rhs.to_bits(), Frac::U32); match dir { - Ordering::Equal => Some($Fixed::from_bits(ans)), + Ordering::Equal => Some(Self::from_bits(ans)), _ => None, } } @@ -2726,31 +2715,31 @@ assert_eq!(Fix::from_bits(bits).rotate_right(3), Fix::from_bits(rot)); /// Checked fixed-point multiplication by integer. #[inline] pub fn checked_mul_int(self, rhs: $Inner) -> Option<$Fixed> { - <$Inner>::checked_mul(self.to_bits(), rhs).map($Fixed::from_bits) + <$Inner>::checked_mul(self.to_bits(), rhs).map(Self::from_bits) } /// Checked fixed-point division by integer. #[inline] pub fn checked_div_int(self, rhs: $Inner) -> Option<$Fixed> { - <$Inner>::checked_div(self.to_bits(), rhs).map($Fixed::from_bits) + <$Inner>::checked_div(self.to_bits(), rhs).map(Self::from_bits) } /// Checked fixed-point remainder for division by integer. #[inline] pub fn checked_rem_int(self, rhs: $Inner) -> Option<$Fixed> { - <$Inner>::checked_rem(self.to_bits(), rhs).map($Fixed::from_bits) + <$Inner>::checked_rem(self.to_bits(), rhs).map(Self::from_bits) } /// Checked fixed-point left shift. #[inline] pub fn checked_shl(self, rhs: u32) -> Option<$Fixed> { - <$Inner>::checked_shl(self.to_bits(), rhs).map($Fixed::from_bits) + <$Inner>::checked_shl(self.to_bits(), rhs).map(Self::from_bits) } /// Checked fixed-point right shift. #[inline] pub fn checked_shr(self, rhs: u32) -> Option<$Fixed> { - <$Inner>::checked_shr(self.to_bits(), rhs).map($Fixed::from_bits) + <$Inner>::checked_shr(self.to_bits(), rhs).map(Self::from_bits) } if_signed! { @@ -2758,110 +2747,110 @@ assert_eq!(Fix::from_bits(bits).rotate_right(3), Fix::from_bits(rot)); /// Checked absolute value. #[inline] pub fn checked_abs(self) -> Option<$Fixed> { - <$Inner>::checked_abs(self.to_bits()).map($Fixed::from_bits) + <$Inner>::checked_abs(self.to_bits()).map(Self::from_bits) } } /// Saturating fixed-point addition. #[inline] pub fn saturating_add(self, rhs: $Fixed) -> $Fixed { - $Fixed::from_bits(<$Inner>::saturating_add(self.to_bits(), rhs.to_bits())) + Self::from_bits(<$Inner>::saturating_add(self.to_bits(), rhs.to_bits())) } /// Saturating fixed-point subtraction. #[inline] pub fn saturating_sub(self, rhs: $Fixed) -> $Fixed { - $Fixed::from_bits(<$Inner>::saturating_sub(self.to_bits(), rhs.to_bits())) + Self::from_bits(<$Inner>::saturating_sub(self.to_bits(), rhs.to_bits())) } /// Saturating fixed-point multiplication. #[inline] pub fn saturating_mul(self, rhs: $Fixed) -> $Fixed { - let (ans, dir) = self.to_bits().mul_dir(rhs.to_bits(), Frac::to_u32()); + let (ans, dir) = self.to_bits().mul_dir(rhs.to_bits(), Frac::U32); match dir { - Ordering::Equal => $Fixed::from_bits(ans), - Ordering::Less => $Fixed::max_value(), - Ordering::Greater => $Fixed::min_value(), + Ordering::Equal => Self::from_bits(ans), + Ordering::Less => Self::max_value(), + Ordering::Greater => Self::min_value(), } } /// Saturating fixed-point division. #[inline] pub fn saturating_div(self, rhs: $Fixed) -> $Fixed { - let (ans, dir) = self.to_bits().div_dir(rhs.to_bits(), Frac::to_u32()); + let (ans, dir) = self.to_bits().div_dir(rhs.to_bits(), Frac::U32); match dir { - Ordering::Equal => $Fixed::from_bits(ans), - Ordering::Less => $Fixed::max_value(), - Ordering::Greater => $Fixed::min_value(), + Ordering::Equal => Self::from_bits(ans), + Ordering::Less => Self::max_value(), + Ordering::Greater => Self::min_value(), } } /// Saturating fixed-point multiplication by integer. #[inline] pub fn saturating_mul_int(self, rhs: $Inner) -> $Fixed { - $Fixed::from_bits(<$Inner>::saturating_mul(self.to_bits(), rhs)) + Self::from_bits(<$Inner>::saturating_mul(self.to_bits(), rhs)) } /// Wrapping negation. #[inline] pub fn wrapping_neg(self) -> $Fixed { - $Fixed::from_bits(<$Inner>::wrapping_neg(self.to_bits())) + Self::from_bits(<$Inner>::wrapping_neg(self.to_bits())) } /// Wrapping fixed-point addition. #[inline] pub fn wrapping_add(self, rhs: $Fixed) -> $Fixed { - $Fixed::from_bits(<$Inner>::wrapping_add(self.to_bits(), rhs.to_bits())) + Self::from_bits(<$Inner>::wrapping_add(self.to_bits(), rhs.to_bits())) } /// Wrapping fixed-point subtraction. #[inline] pub fn wrapping_sub(self, rhs: $Fixed) -> $Fixed { - $Fixed::from_bits(<$Inner>::wrapping_sub(self.to_bits(), rhs.to_bits())) + Self::from_bits(<$Inner>::wrapping_sub(self.to_bits(), rhs.to_bits())) } /// Wrapping fixed-point multiplication. #[inline] pub fn wrapping_mul(self, rhs: $Fixed) -> $Fixed { - let (ans, _dir) = self.to_bits().mul_dir(rhs.to_bits(), Frac::to_u32()); - $Fixed::from_bits(ans) + let (ans, _dir) = self.to_bits().mul_dir(rhs.to_bits(), Frac::U32); + Self::from_bits(ans) } /// Wrapping fixed-point division. #[inline] pub fn wrapping_div(self, rhs: $Fixed) -> $Fixed { - let (ans, _dir) = self.to_bits().div_dir(rhs.to_bits(), Frac::to_u32()); - $Fixed::from_bits(ans) + let (ans, _dir) = self.to_bits().div_dir(rhs.to_bits(), Frac::U32); + Self::from_bits(ans) } /// Wrapping fixed-point multiplication by integer. #[inline] pub fn wrapping_mul_int(self, rhs: $Inner) -> $Fixed { - $Fixed::from_bits(<$Inner>::wrapping_mul(self.to_bits(), rhs)) + Self::from_bits(<$Inner>::wrapping_mul(self.to_bits(), rhs)) } /// Wrapping fixed-point division by integer. #[inline] pub fn wrapping_div_int(self, rhs: $Inner) -> $Fixed { - $Fixed::from_bits(<$Inner>::wrapping_div(self.to_bits(), rhs)) + Self::from_bits(<$Inner>::wrapping_div(self.to_bits(), rhs)) } /// Wrapping fixed-point remainder for division by integer. #[inline] pub fn wrapping_rem_int(self, rhs: $Inner) -> $Fixed { - $Fixed::from_bits(<$Inner>::wrapping_rem(self.to_bits(), rhs)) + Self::from_bits(<$Inner>::wrapping_rem(self.to_bits(), rhs)) } /// Wrapping fixed-point left shift. #[inline] pub fn wrapping_shl(self, rhs: u32) -> $Fixed { - $Fixed::from_bits(<$Inner>::wrapping_shl(self.to_bits(), rhs)) + Self::from_bits(<$Inner>::wrapping_shl(self.to_bits(), rhs)) } /// Wrapping fixed-point right shift. #[inline] pub fn wrapping_shr(self, rhs: u32) -> $Fixed { - $Fixed::from_bits(<$Inner>::wrapping_shr(self.to_bits(), rhs)) + Self::from_bits(<$Inner>::wrapping_shr(self.to_bits(), rhs)) } if_signed! { @@ -2869,7 +2858,7 @@ assert_eq!(Fix::from_bits(bits).rotate_right(3), Fix::from_bits(rot)); /// Wrapping absolute value. #[inline] pub fn wrapping_abs(self) -> $Fixed { - $Fixed::from_bits(<$Inner>::wrapping_abs(self.to_bits())) + Self::from_bits(<$Inner>::wrapping_abs(self.to_bits())) } } @@ -2877,70 +2866,70 @@ assert_eq!(Fix::from_bits(bits).rotate_right(3), Fix::from_bits(rot)); #[inline] pub fn overflowing_neg(self) -> ($Fixed, bool) { let (ans, o) = <$Inner>::overflowing_neg(self.to_bits()); - ($Fixed::from_bits(ans), o) + (Self::from_bits(ans), o) } /// Overflowing fixed-point addition. #[inline] pub fn overflowing_add(self, rhs: $Fixed) -> ($Fixed, bool) { let (ans, o) = <$Inner>::overflowing_add(self.to_bits(), rhs.to_bits()); - ($Fixed::from_bits(ans), o) + (Self::from_bits(ans), o) } /// Overflowing fixed-point subtraction. #[inline] pub fn overflowing_sub(self, rhs: $Fixed) -> ($Fixed, bool) { let (ans, o) = <$Inner>::overflowing_sub(self.to_bits(), rhs.to_bits()); - ($Fixed::from_bits(ans), o) + (Self::from_bits(ans), o) } /// Overflowing fixed-point multiplication. #[inline] pub fn overflowing_mul(self, rhs: $Fixed) -> ($Fixed, bool) { - let (ans, dir) = self.to_bits().mul_dir(rhs.to_bits(), Frac::to_u32()); - ($Fixed::from_bits(ans), dir != Ordering::Equal) + let (ans, dir) = self.to_bits().mul_dir(rhs.to_bits(), Frac::U32); + (Self::from_bits(ans), dir != Ordering::Equal) } /// Overflowing fixed-point division. #[inline] pub fn overflowing_div(self, rhs: $Fixed) -> ($Fixed, bool) { - let (ans, dir) = self.to_bits().div_dir(rhs.to_bits(), Frac::to_u32()); - ($Fixed::from_bits(ans), dir != Ordering::Equal) + let (ans, dir) = self.to_bits().div_dir(rhs.to_bits(), Frac::U32); + (Self::from_bits(ans), dir != Ordering::Equal) } /// Overflowing fixed-point multiplication by integer. #[inline] pub fn overflowing_mul_int(self, rhs: $Inner) -> ($Fixed, bool) { let (ans, o) = <$Inner>::overflowing_mul(self.to_bits(), rhs); - ($Fixed::from_bits(ans), o) + (Self::from_bits(ans), o) } /// Overflowing fixed-point division by integer. #[inline] pub fn overflowing_div_int(self, rhs: $Inner) -> ($Fixed, bool) { let (ans, o) = <$Inner>::overflowing_div(self.to_bits(), rhs); - ($Fixed::from_bits(ans), o) + (Self::from_bits(ans), o) } /// Overflowing fixed-point remainder for division by integer. #[inline] pub fn overflowing_rem_int(self, rhs: $Inner) -> ($Fixed, bool) { let (ans, o) = <$Inner>::overflowing_rem(self.to_bits(), rhs); - ($Fixed::from_bits(ans), o) + (Self::from_bits(ans), o) } /// Overflowing fixed-point left shift. #[inline] pub fn overflowing_shl(self, rhs: u32) -> ($Fixed, bool) { let (ans, o) = <$Inner>::overflowing_shl(self.to_bits(), rhs); - ($Fixed::from_bits(ans), o) + (Self::from_bits(ans), o) } /// Overflowing fixed-point right shift. #[inline] pub fn overflowing_shr(self, rhs: u32) -> ($Fixed, bool) { let (ans, o) = <$Inner>::overflowing_shr(self.to_bits(), rhs); - ($Fixed::from_bits(ans), o) + (Self::from_bits(ans), o) } if_signed! { @@ -2949,7 +2938,7 @@ assert_eq!(Fix::from_bits(bits).rotate_right(3), Fix::from_bits(rot)); #[inline] pub fn overflowing_abs(self) -> ($Fixed, bool) { let (ans, o) = <$Inner>::overflowing_abs(self.to_bits()); - ($Fixed::from_bits(ans), o) + (Self::from_bits(ans), o) } } @@ -3036,7 +3025,7 @@ assert!(Fix::max_value().checked_next_power_of_two().is_none()); ), #[inline] pub fn checked_next_power_of_two(self) -> Option<$Fixed> { - <$Inner>::checked_next_power_of_two(self.to_bits()).map($Fixed::from_bits) + <$Inner>::checked_next_power_of_two(self.to_bits()).map(Self::from_bits) } ); } @@ -3097,13 +3086,9 @@ assert_eq!(Fix::from_int(-5).signum(), -1); #[inline] pub fn signum(self) -> $Fixed { match self.to_bits().cmp(&0) { - Ordering::Equal => $Fixed::from_bits(0), - Ordering::Greater => { - <$Fixed as SealedFixed>::one().expect("overflow") - } - Ordering::Less => { - <$Fixed as SealedFixed>::minus_one().expect("overflow") - } + Ordering::Equal => Self::from_bits(0), + Ordering::Greater => Self::one().expect("overflow"), + Ordering::Less => Self::minus_one().expect("overflow"), } } ); diff --git a/src/sealed_fixed.rs b/src/sealed_fixed.rs index 6f861cb..8e0dbe1 100644 --- a/src/sealed_fixed.rs +++ b/src/sealed_fixed.rs @@ -39,8 +39,10 @@ pub trait SealedFixed: Copy + Debug + Display { // split shift in two parts in case that FRAC_NBITS == 128 const INT_MASK: u128 = !0 << (Self::FRAC_NBITS / 2) << (Self::FRAC_NBITS - Self::FRAC_NBITS / 2); - const FRAC_HI: u128 = Self::FRAC_MASK ^ (Self::FRAC_MASK >> 1); - const INT_LO: u128 = Self::INT_MASK ^ (Self::INT_MASK << 1); + // 0 for no frac bits + const FRAC_MSB: u128 = Self::FRAC_MASK ^ (Self::FRAC_MASK >> 1); + // 0 for no int bits + const INT_LSB: u128 = Self::INT_MASK ^ (Self::INT_MASK << 1); fn from_fixed(fixed: F) -> Self where @@ -65,13 +67,6 @@ pub trait SealedFixed: Copy + Debug + Display { } } - fn frac_mask() -> Self::Bits; - fn int_mask() -> Self::Bits; - // 0 for no frac bits - fn highest_frac_bit() -> Self::Bits; - // 0 for no int bits - fn lowest_int_bit() -> Self::Bits; - fn from_bits(bits: Self::Bits) -> Self; fn to_bits(self) -> Self::Bits; fn parts( @@ -100,26 +95,6 @@ macro_rules! sealed_fixed { $Fixed::from_fixed(fixed) } - #[inline] - fn frac_mask() -> Self::Bits { - Self::FRAC_MASK as _ - } - - #[inline] - fn int_mask() -> Self::Bits { - Self::INT_MASK as _ - } - - #[inline] - fn highest_frac_bit() -> Self::Bits { - Self::FRAC_HI as _ - } - - #[inline] - fn lowest_int_bit() -> Self::Bits { - Self::INT_LO as _ - } - #[inline] fn from_bits(bits: Self::Bits) -> Self { $Fixed::from_bits(bits) @@ -138,16 +113,13 @@ macro_rules! sealed_fixed { ::Unsigned, ::Unsigned, ) { - let frac_bits = ::FRAC_NBITS; - let int_bits = ::INT_NBITS; - let (neg, abs) = SealedInt::neg_abs(self.to_bits()); - let (int_abs, frac_abs) = if int_bits == 0 { + let (int_abs, frac_abs) = if Self::INT_NBITS == 0 { (0, abs) - } else if frac_bits == 0 { + } else if Self::FRAC_NBITS == 0 { (abs, 0) } else { - ((abs >> frac_bits), (abs << int_bits)) + ((abs >> Self::FRAC_NBITS), (abs << Self::INT_NBITS)) }; (neg, int_abs, frac_abs) } diff --git a/src/sealed_float.rs b/src/sealed_float.rs index f70c225..790721d 100644 --- a/src/sealed_float.rs +++ b/src/sealed_float.rs @@ -21,31 +21,24 @@ use sealed::SealedInt; pub trait SealedFloat: Copy + Debug + Display { type Bits: SealedInt; - fn prec() -> u32; - - #[inline] - fn exp_bias() -> i32 { - let nbits = Self::Bits::NBITS; - let exp_bits = nbits - Self::prec(); - (1 << (exp_bits - 1)) - 1 - } - - #[inline] - fn exp_min() -> i32 { - 1 - Self::exp_bias() - } - - #[inline] - fn exp_max() -> i32 { - Self::exp_bias() - } + const PREC: u32; + const EXP_BIAS: i32 = (1 << (Self::Bits::NBITS - Self::PREC - 1)) - 1; + const EXP_MIN: i32 = 1 - Self::EXP_BIAS; + const EXP_MAX: i32 = Self::EXP_BIAS; + const SIGN_MASK: Self::Bits; + const EXP_MASK: Self::Bits; + const MANT_MASK: Self::Bits; fn zero(neg: bool) -> Self; fn infinity(neg: bool) -> Self; + fn is_nan(self) -> bool; fn is_finite(self) -> bool; + fn is_zero(self) -> bool; fn is_sign_positive(self) -> bool; + fn is_sign_negative(self) -> bool; fn parts(self) -> (bool, i32, Self::Bits); + fn from_parts(sign: bool, exp: i32, mant: Self::Bits) -> Self; fn from_neg_abs(neg: bool, abs: u128, frac_bits: u32, int_bits: u32) -> Self; // self must be finite, otherwise meaningless results are returned @@ -57,65 +50,69 @@ macro_rules! sealed_float { impl SealedFloat for $Float { type Bits = $Bits; - #[inline] - fn prec() -> u32 { - $prec - } + const PREC: u32 = $prec; + const SIGN_MASK: Self::Bits = Self::Bits::MSB; + const EXP_MASK: Self::Bits = Self::SIGN_MASK - (1 << (Self::PREC - 1)); + const MANT_MASK: Self::Bits = (1 << (Self::PREC - 1)) - 1; #[inline] fn zero(neg: bool) -> $Float { - let nbits = ::NBITS; - let neg_mask = !0 << (nbits - 1); - let neg_bits = if neg { neg_mask } else { 0 }; - <$Float>::from_bits(neg_bits) + Self::from_bits(if neg { Self::SIGN_MASK } else { 0 }) } #[inline] fn infinity(neg: bool) -> $Float { - let nbits = ::NBITS; - let neg_mask = !0 << (nbits - 1); - let mant_mask = !(!0 << ($prec - 1)); - let exp_mask = !(neg_mask | mant_mask); + Self::from_bits(Self::EXP_MASK | if neg { Self::SIGN_MASK } else { 0 }) + } - let neg_bits = if neg { neg_mask } else { 0 }; - <$Float>::from_bits(neg_bits | exp_mask) + #[inline] + fn is_nan(self) -> bool { + (self.to_bits() & !Self::SIGN_MASK) > Self::EXP_MASK } #[inline] fn is_finite(self) -> bool { - self.is_finite() + (self.to_bits() & !Self::SIGN_MASK) < Self::EXP_MASK + } + + #[inline] + fn is_zero(self) -> bool { + (self.to_bits() & !Self::SIGN_MASK) == 0 } #[inline] fn is_sign_positive(self) -> bool { - self.is_sign_positive() + (self.to_bits() & Self::SIGN_MASK) == 0 } #[inline] - fn parts(self) -> (bool, i32, $Bits) { - let nbits = ::NBITS; - let neg_mask = !0 << (nbits - 1); - let mant_mask = !(!0 << ($prec - 1)); - let exp_mask = !(neg_mask | mant_mask); + fn is_sign_negative(self) -> bool { + (self.to_bits() & Self::SIGN_MASK) != 0 + } + #[inline] + #[cfg_attr(feature = "cargo-clippy", allow(clippy::cast_lossless))] + fn parts(self) -> (bool, i32, $Bits) { let bits = self.to_bits(); - let neg = bits & neg_mask != 0; - let biased_exp = (bits & exp_mask) >> ($prec - 1); - let exp = ({ - #[cfg_attr(feature = "cargo-clippy", allow(clippy::cast_lossless))] - { - biased_exp as i32 - } - }) - <$Float as SealedFloat>::exp_bias(); - let mant = bits & mant_mask; + let neg = bits & Self::SIGN_MASK != 0; + let biased_exp = (bits & Self::EXP_MASK) >> (Self::PREC - 1); + let exp = biased_exp as i32 - Self::EXP_BIAS; + let mant = bits & Self::MANT_MASK; (neg, exp, mant) } + #[inline] + #[cfg_attr(feature = "cargo-clippy", allow(clippy::cast_lossless))] + fn from_parts(sign: bool, exp: i32, mant: $Bits) -> Self { + let sign_bits = if sign { Self::SIGN_MASK } else { 0 }; + let biased_exp = (exp + Self::EXP_BIAS) as Self::Bits; + let exp_bits = biased_exp << (Self::PREC - 1); + let bits = sign_bits | exp_bits | mant; + Self::from_bits(bits) + } + fn from_neg_abs(neg: bool, abs: u128, frac_bits: u32, int_bits: u32) -> $Float { - let prec = Self::prec(); - let exp_min = Self::exp_min(); - let exp_max = Self::exp_max(); let fix_bits = frac_bits + int_bits; let extra_zeros = 128 - fix_bits; @@ -127,10 +124,10 @@ macro_rules! sealed_float { // remove leading zeros and implicit one let mut mantissa = abs << leading_zeros << 1; let exponent = int_bits as i32 - 1 - leading_zeros as i32; - let biased_exponent = if exponent > exp_max { + let biased_exponent = if exponent > Self::EXP_MAX { return Self::infinity(neg); - } else if exponent < exp_min { - let lost_prec = exp_min - exponent; + } else if exponent < Self::EXP_MIN { + let lost_prec = Self::EXP_MIN - exponent; if lost_prec as u32 >= (int_bits + frac_bits) { mantissa = 0; } else { @@ -140,11 +137,11 @@ macro_rules! sealed_float { } 0 } else { - (exponent + exp_max) as Self::Bits + (exponent + Self::EXP_MAX) as Self::Bits }; // check for rounding - let round_up = (fix_bits >= prec) && { - let shift = prec - 1; + let round_up = (fix_bits >= Self::PREC) && { + let shift = Self::PREC - 1; let mid_bit = !(!0 >> 1) >> (shift + extra_zeros); let lower_bits = mid_bit - 1; if mantissa & mid_bit == 0 { @@ -157,12 +154,12 @@ macro_rules! sealed_float { } }; let bits_sign = if neg { !(!0 >> 1) } else { 0 }; - let bits_exp = biased_exponent << (prec - 1); - let bits_mantissa = (if fix_bits >= prec - 1 { - (mantissa >> (fix_bits - (prec - 1))) as Self::Bits + let bits_exp = biased_exponent << (Self::PREC - 1); + let bits_mantissa = (if fix_bits >= Self::PREC - 1 { + (mantissa >> (fix_bits - (Self::PREC - 1))) as Self::Bits } else { - (mantissa as Self::Bits) << (prec - 1 - fix_bits) - }) & !(!0 << (prec - 1)); + (mantissa as Self::Bits) << (Self::PREC - 1 - fix_bits) + }) & !(!0 << (Self::PREC - 1)); let mut bits_exp_mantissa = bits_exp | bits_mantissa; if round_up { bits_exp_mantissa += 1; @@ -176,13 +173,13 @@ macro_rules! sealed_float { int_bits: u32, ) -> (bool, u128, bool) { let float_bits = Self::Bits::NBITS as i32; - let prec = Self::prec() as i32; + let prec = Self::PREC as i32; let fix_bits = (frac_bits + int_bits) as i32; let (neg, exp, mut mantissa) = self.parts(); - debug_assert!(exp <= Self::exp_max(), "not finite"); + debug_assert!(exp <= Self::EXP_MAX, "not finite"); // if not subnormal, add implicit bit - if exp >= Self::exp_min() { + if exp >= Self::EXP_MIN { mantissa |= 1 << (prec - 1); } if mantissa == 0 { diff --git a/src/sealed_int.rs b/src/sealed_int.rs index 9689676..00ed887 100644 --- a/src/sealed_int.rs +++ b/src/sealed_int.rs @@ -29,6 +29,8 @@ pub trait SealedInt: Copy + Ord + Debug + Display { fn one_shl(shift: u32) -> Self; fn all_ones_shl(shift: u32) -> Self; fn is_zero(self) -> bool; + fn is_positive(self) -> bool; + fn is_negative(self) -> bool; fn to_fixed_overflow( self, @@ -65,6 +67,11 @@ macro_rules! sealed_int { self == 0 } + #[inline] + fn is_positive(self) -> bool { + self > 0 + } + $($rest)* } }; @@ -72,6 +79,11 @@ macro_rules! sealed_int { sealed_int! { $Unsigned($NBits, False, $Unsigned); + #[inline] + fn is_negative(self) -> bool { + false + } + #[inline] fn neg_abs(self) -> (bool, Self::Unsigned) { (false, self) @@ -91,7 +103,7 @@ macro_rules! sealed_int { dst_frac_bits: u32, dst_int_bits: u32, ) -> (Widest, bool) { - let src_bits = ::NBITS as i32; + let src_bits = Self::NBITS as i32; let dst_bits = (dst_frac_bits + dst_int_bits) as i32; if self == 0 { @@ -120,6 +132,11 @@ macro_rules! sealed_int { sealed_int! { $Signed($NBits, True, $Unsigned); + #[inline] + fn is_negative(self) -> bool { + false + } + #[inline] fn neg_abs(self) -> (bool, Self::Unsigned) { if self < 0 { @@ -146,7 +163,7 @@ macro_rules! sealed_int { dst_frac_bits: u32, dst_int_bits: u32, ) -> (Widest, bool) { - let src_bits = ::NBITS as i32; + let src_bits = Self::NBITS as i32; let dst_bits = (dst_frac_bits + dst_int_bits) as i32; if self >= 0 { @@ -204,6 +221,16 @@ impl SealedInt for bool { !self } + #[inline] + fn is_positive(self) -> bool { + self + } + + #[inline] + fn is_negative(self) -> bool { + false + } + #[inline] fn to_fixed_overflow( self, diff --git a/src/wide_div.rs b/src/wide_div.rs index b554a83..59f482d 100644 --- a/src/wide_div.rs +++ b/src/wide_div.rs @@ -13,6 +13,8 @@ // and // . +use sealed::SealedInt; + trait DivHalf: Copy { fn hi(self) -> Self; fn lo(self) -> Self; @@ -85,37 +87,15 @@ macro_rules! div_half { div_half! { u8: 8, u16: 16, u32: 32, u64: 64, u128: 128 } -trait NegAbs { +trait NegAbsHiLo { type Abs; fn neg_abs(self) -> (bool, Self::Abs); fn from_neg_abs(neg: bool, abs: Self::Abs) -> Self; } -macro_rules! neg_abs { +macro_rules! neg_abs_hi_lo { ($($S:ty: $U:ty),*) => { $( - impl NegAbs for $S { - type Abs = $U; - - #[inline] - fn neg_abs(self) -> (bool, $U) { - if self < 0 { - (true, self.wrapping_neg() as $U) - } else { - (false, self as $U) - } - } - - #[inline] - fn from_neg_abs(neg: bool, abs: $U) -> $S { - if neg { - abs.wrapping_neg() as $S - } else { - abs as $S - } - } - } - - impl NegAbs for ($S, $U) { + impl NegAbsHiLo for ($S, $U) { type Abs = ($U, $U); #[inline] @@ -145,7 +125,7 @@ macro_rules! neg_abs { )* }; } -neg_abs! { i8: u8, i16: u16, i32: u32, i64: u64, i128: u128 } +neg_abs_hi_lo! { i8: u8, i16: u16, i32: u32, i64: u64, i128: u128 } pub trait WideDivRem: Sized { fn div_rem_from(self, dividend: (Self, U)) -> ((Self, U), Self); @@ -176,8 +156,8 @@ macro_rules! signed_wide_div_rem { let (d_neg, d_abs) = self.neg_abs(); let (q, r) = d_abs.div_rem_from(n_abs); ( - NegAbs::from_neg_abs(n_neg != d_neg, q), - NegAbs::from_neg_abs(n_neg, r), + NegAbsHiLo::from_neg_abs(n_neg != d_neg, q), + SealedInt::from_neg_abs(n_neg, r), ) } }