code cleanups

This commit is contained in:
Trevor Spiteri 2019-01-31 01:58:59 +01:00
parent aa707df6c9
commit f7d2fc18e0
9 changed files with 389 additions and 444 deletions

View File

@ -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<Frac>;
#[inline]
fn $method(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
<$Fixed<Frac> as $Imp<$Fixed<Frac>>>::$method(*self, rhs)
(*self).$method(rhs)
}
}
@ -48,7 +47,7 @@ macro_rules! refs {
type Output = $Fixed<Frac>;
#[inline]
fn $method(self, rhs: &$Fixed<Frac>) -> $Fixed<Frac> {
<$Fixed<Frac> as $Imp<$Fixed<Frac>>>::$method(self, *rhs)
self.$method(*rhs)
}
}
@ -59,7 +58,7 @@ macro_rules! refs {
type Output = $Fixed<Frac>;
#[inline]
fn $method(self, rhs: &$Fixed<Frac>) -> $Fixed<Frac> {
<$Fixed<Frac> as $Imp<$Fixed<Frac>>>::$method(*self, *rhs)
(*self).$method(*rhs)
}
}
};
@ -73,7 +72,7 @@ macro_rules! refs_assign {
{
#[inline]
fn $method(&mut self, rhs: &$Fixed<Frac>) {
<$Fixed<Frac> as $Imp<$Fixed<Frac>>>::$method(self, *rhs);
self.$method(*rhs);
}
}
};
@ -88,10 +87,7 @@ macro_rules! pass {
type Output = $Fixed<Frac>;
#[inline]
fn $method(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
$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<Frac>) {
<$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<Frac>;
#[inline]
fn $method(self) -> $Fixed<Frac> {
$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<Frac>;
#[inline]
fn $method(self) -> $Fixed<Frac> {
<$Fixed<Frac> as $Imp>::$method(*self)
(*self).$method()
}
}
};
@ -150,7 +146,7 @@ macro_rules! shift {
type Output = $Fixed<Frac>;
#[inline]
fn $method(self, rhs: $Rhs) -> $Fixed<Frac> {
$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<Frac>;
#[inline]
fn $method(self, rhs: $Rhs) -> $Fixed<Frac> {
<$Fixed<Frac> as $Imp<$Rhs>>::$method(*self, rhs)
(*self).$method(rhs)
}
}
@ -172,7 +168,7 @@ macro_rules! shift {
type Output = $Fixed<Frac>;
#[inline]
fn $method(self, rhs: &$Rhs) -> $Fixed<Frac> {
<$Fixed<Frac> as $Imp<$Rhs>>::$method(self, *rhs)
self.$method(*rhs)
}
}
@ -183,7 +179,7 @@ macro_rules! shift {
type Output = $Fixed<Frac>;
#[inline]
fn $method(self, rhs: &$Rhs) -> $Fixed<Frac> {
<$Fixed<Frac> 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<Frac> as $Imp<$Rhs>>::$method(self, *rhs);
self.$method(*rhs)
}
}
};
@ -242,9 +238,9 @@ macro_rules! fixed_arith {
type Output = $Fixed<Frac>;
#[inline]
fn mul(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
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<Frac>) {
*self = <$Fixed<Frac> as Mul<$Fixed<Frac>>>::mul(*self, rhs)
*self = (*self).mul(rhs)
}
}
@ -269,9 +265,9 @@ macro_rules! fixed_arith {
type Output = $Fixed<Frac>;
#[inline]
fn div(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
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<Frac>) {
*self = <$Fixed<Frac> as Div<$Fixed<Frac>>>::div(*self, rhs)
*self = (*self).div(rhs)
}
}
@ -304,7 +300,7 @@ macro_rules! fixed_arith {
type Output = $Fixed<Frac>;
#[inline]
fn mul(self, rhs: $Inner) -> $Fixed<Frac> {
$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<Frac>;
#[inline]
fn mul(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
<$Fixed<Frac> as Mul<$Inner>>::mul(rhs, self)
rhs.mul(self)
}
}
@ -326,7 +322,7 @@ macro_rules! fixed_arith {
type Output = $Fixed<Frac>;
#[inline]
fn mul(self, rhs: $Inner) -> $Fixed<Frac> {
<$Fixed<Frac> as Mul<$Inner>>::mul(*self, rhs)
(*self).mul(rhs)
}
}
@ -337,7 +333,7 @@ macro_rules! fixed_arith {
type Output = $Fixed<Frac>;
#[inline]
fn mul(self, rhs: &$Fixed<Frac>) -> $Fixed<Frac> {
<$Fixed<Frac> as Mul<$Inner>>::mul(*rhs, self)
(*rhs).mul(self)
}
}
@ -348,7 +344,7 @@ macro_rules! fixed_arith {
type Output = $Fixed<Frac>;
#[inline]
fn mul(self, rhs: &$Inner) -> $Fixed<Frac> {
<$Fixed<Frac> as Mul<$Inner>>::mul(self, *rhs)
self.mul(*rhs)
}
}
@ -359,7 +355,7 @@ macro_rules! fixed_arith {
type Output = $Fixed<Frac>;
#[inline]
fn mul(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
<$Fixed<Frac> as Mul<$Inner>>::mul(rhs, *self)
rhs.mul(*self)
}
}
@ -370,7 +366,7 @@ macro_rules! fixed_arith {
type Output = $Fixed<Frac>;
#[inline]
fn mul(self, rhs: &$Inner) -> $Fixed<Frac> {
<$Fixed<Frac> as Mul<$Inner>>::mul(*self, *rhs)
(*self).mul(*rhs)
}
}
@ -381,7 +377,7 @@ macro_rules! fixed_arith {
type Output = $Fixed<Frac>;
#[inline]
fn mul(self, rhs: &$Fixed<Frac>) -> $Fixed<Frac> {
<$Fixed<Frac> 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<Frac> 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<Frac> as Mul<$Inner>>::mul(*self, *rhs)
*self = (*self).mul(*rhs);
}
}
@ -412,7 +408,7 @@ macro_rules! fixed_arith {
type Output = $Fixed<Frac>;
#[inline]
fn div(self, rhs: $Inner) -> $Fixed<Frac> {
$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<Frac>;
#[inline]
fn div(self, rhs: $Inner) -> $Fixed<Frac> {
<$Fixed<Frac> as Div<$Inner>>::div(*self, rhs)
(*self).div(rhs)
}
}
@ -434,7 +430,7 @@ macro_rules! fixed_arith {
type Output = $Fixed<Frac>;
#[inline]
fn div(self, rhs: &$Inner) -> $Fixed<Frac> {
<$Fixed<Frac> as Div<$Inner>>::div(self, *rhs)
self.div(*rhs)
}
}
impl<'a, 'b, Frac> Div<&'a $Inner> for &'b $Fixed<Frac>
@ -444,7 +440,7 @@ macro_rules! fixed_arith {
type Output = $Fixed<Frac>;
#[inline]
fn div(self, rhs: &$Inner) -> $Fixed<Frac> {
<$Fixed<Frac> 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<Frac> 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<Frac> as Div<$Inner>>::div(*self, *rhs)
*self = (*self).div(*rhs);
}
}
@ -475,7 +471,7 @@ macro_rules! fixed_arith {
type Output = $Fixed<Frac>;
#[inline]
fn rem(self, rhs: $Inner) -> $Fixed<Frac> {
$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<Frac>;
#[inline]
fn rem(self, rhs: $Inner) -> $Fixed<Frac> {
<$Fixed<Frac> as Rem<$Inner>>::rem(*self, rhs)
(*self).rem(rhs)
}
}
@ -497,7 +493,7 @@ macro_rules! fixed_arith {
type Output = $Fixed<Frac>;
#[inline]
fn rem(self, rhs: &$Inner) -> $Fixed<Frac> {
<$Fixed<Frac> as Rem<$Inner>>::rem(self, *rhs)
self.rem(*rhs)
}
}
@ -508,7 +504,7 @@ macro_rules! fixed_arith {
type Output = $Fixed<Frac>;
#[inline]
fn rem(self, rhs: &$Inner) -> $Fixed<Frac> {
<$Fixed<Frac> 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<Frac> 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<Frac> 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<I: Iterator<Item = $Fixed<Frac>>>(iter: I) -> $Fixed<Frac> {
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<I: Iterator<Item = &'a $Fixed<Frac>>>(iter: I) -> $Fixed<Frac> {
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<I: Iterator<Item = $Fixed<Frac>>>(mut iter: I) -> $Fixed<Frac> {
match iter.next() {
None => <$Fixed<Frac> 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<I: Iterator<Item = &'a $Fixed<Frac>>>(mut iter: I) -> $Fixed<Frac> {
match iter.next() {
None => <$Fixed<Frac> 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(&quot2);
let dir = <$Double>::from(quot).cmp(&quot2);
(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 {
let dir = if !overflow {
Ordering::Equal
} else {
Ordering::Less
};
}
if_signed! {
$Signedness;
dir = if !overflow {
Ordering::Equal
} else if (self < 0) == (rhs < 0) {
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 {
let dir = if !overflow {
Ordering::Equal
} else {
Ordering::Less
};
}
if_signed! {
$Signedness;
dir = if !overflow {
Ordering::Equal
} else if (self < 0) == (rhs < 0) {
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(&quot2.0)
.then((quot2_ret.1).cmp(&quot2.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::<Frac>::from_bits(a << Frac::to_u32());
let bf = FixedU16::<Frac>::from_bits(b << Frac::to_u32());
let af = FixedU16::<Frac>::from_bits(a << Frac::U32);
let bf = FixedU16::<Frac>::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 &[

View File

@ -14,7 +14,7 @@
// <https://opensource.org/licenses/MIT>.
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<FracRhs>) -> 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<Frac> as PartialEq<$Fixed<frac::U0>>>::eq(self, &$Fixed::from_bits(*rhs))
self.eq(&$Fixed::<U0>::from_bits(*rhs))
}
}
@ -66,7 +66,7 @@ macro_rules! fixed_cmp {
{
#[inline]
fn eq(&self, rhs: &$Fixed<Frac>) -> bool {
<$Fixed<frac::U0> as PartialEq<$Fixed<Frac>>>::eq(&$Fixed::from_bits(*self), rhs)
$Fixed::<U0>::from_bits(*self).eq(rhs)
}
}
@ -87,7 +87,7 @@ macro_rules! fixed_cmp {
{
#[inline]
fn partial_cmp(&self, rhs: &$Fixed<FracRhs>) -> Option<Ordering> {
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<FracRhs>) -> 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<FracRhs>) -> 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<Ordering> {
self.partial_cmp(&$Fixed::<frac::U0>::from_bits(*rhs))
self.partial_cmp(&$Fixed::<U0>::from_bits(*rhs))
}
#[inline]
fn lt(&self, rhs: &$Inner) -> bool {
self.lt(&$Fixed::<frac::U0>::from_bits(*rhs))
self.lt(&$Fixed::<U0>::from_bits(*rhs))
}
#[inline]
fn le(&self, rhs: &$Inner) -> bool {
self.le(&$Fixed::<frac::U0>::from_bits(*rhs))
self.le(&$Fixed::<U0>::from_bits(*rhs))
}
#[inline]
fn gt(&self, rhs: &$Inner) -> bool {
self.gt(&$Fixed::<frac::U0>::from_bits(*rhs))
self.gt(&$Fixed::<U0>::from_bits(*rhs))
}
#[inline]
fn ge(&self, rhs: &$Inner) -> bool {
self.ge(&$Fixed::<frac::U0>::from_bits(*rhs))
self.ge(&$Fixed::<U0>::from_bits(*rhs))
}
}
@ -200,27 +200,27 @@ macro_rules! fixed_cmp {
{
#[inline]
fn partial_cmp(&self, rhs: &$Fixed<Frac>) -> Option<Ordering> {
$Fixed::<frac::U0>::from_bits(*self).partial_cmp(rhs)
$Fixed::<U0>::from_bits(*self).partial_cmp(rhs)
}
#[inline]
fn lt(&self, rhs: &$Fixed<Frac>) -> bool {
$Fixed::<frac::U0>::from_bits(*self).lt(rhs)
$Fixed::<U0>::from_bits(*self).lt(rhs)
}
#[inline]
fn le(&self, rhs: &$Fixed<Frac>) -> bool {
$Fixed::<frac::U0>::from_bits(*self).le(rhs)
$Fixed::<U0>::from_bits(*self).le(rhs)
}
#[inline]
fn gt(&self, rhs: &$Fixed<Frac>) -> bool {
$Fixed::<frac::U0>::from_bits(*self).gt(rhs)
$Fixed::<U0>::from_bits(*self).gt(rhs)
}
#[inline]
fn ge(&self, rhs: &$Fixed<Frac>) -> bool {
$Fixed::<frac::U0>::from_bits(*self).ge(rhs)
$Fixed::<U0>::from_bits(*self).ge(rhs)
}
}
};

View File

@ -39,7 +39,7 @@ macro_rules! convert {
#[inline]
fn from(src: $SrcU<FracSrc>) -> $DstU<FracDst> {
let unshifted = $DstU::<FracDst>::from_bits(src.to_bits().into()).to_bits();
let shift = FracDst::to_u32() - FracSrc::to_u32();
let shift = FracDst::U32 - FracSrc::U32;
$DstU::<FracDst>::from_bits(unshifted << shift)
}
}
@ -59,7 +59,7 @@ macro_rules! convert {
#[inline]
fn from(src: $SrcI<FracSrc>) -> $DstI<FracDst> {
let unshifted = $DstI::<FracDst>::from_bits(src.to_bits().into()).to_bits();
let shift = FracDst::to_u32() - FracSrc::to_u32();
let shift = FracDst::U32 - FracSrc::U32;
$DstI::<FracDst>::from_bits(unshifted << shift)
}
}
@ -82,7 +82,7 @@ macro_rules! convert {
#[inline]
fn from(src: $SrcU<FracSrc>) -> $DstI<FracDst> {
let unshifted = $DstI::<FracDst>::from_bits(src.to_bits().into()).to_bits();
let shift = FracDst::to_u32() - FracSrc::to_u32();
let shift = FracDst::U32 - FracSrc::U32;
$DstI::<FracDst>::from_bits(unshifted << shift)
}
}
@ -115,7 +115,7 @@ macro_rules! prim_to_fixed {
#[inline]
fn from(src: $SrcU) -> $DstU<FracDst> {
let unshifted = $DstU::<FracDst>::from_bits(src.into()).to_bits();
let shift = FracDst::to_u32();
let shift = FracDst::U32;
$DstU::<FracDst>::from_bits(unshifted << shift)
}
}
@ -130,7 +130,7 @@ macro_rules! prim_to_fixed {
#[inline]
fn from(src: $SrcI) -> $DstI<FracDst> {
let unshifted = $DstI::<FracDst>::from_bits(src.into()).to_bits();
let shift = FracDst::to_u32();
let shift = FracDst::U32;
$DstI::<FracDst>::from_bits(unshifted << shift)
}
}
@ -148,7 +148,7 @@ macro_rules! prim_to_fixed {
#[inline]
fn from(src: $SrcU) -> $DstI<FracDst> {
let unshifted = $DstI::<FracDst>::from_bits(src.into()).to_bits();
let shift = FracDst::to_u32();
let shift = FracDst::U32;
$DstI::<FracDst>::from_bits(unshifted << shift)
}
}
@ -203,7 +203,7 @@ macro_rules! bool_to_fixed {
#[inline]
fn from(src: bool) -> $DstU<FracDst> {
let unshifted = $DstU::<FracDst>::from_bits(src.into()).to_bits();
let shift = FracDst::to_u32();
let shift = FracDst::U32;
$DstU::<FracDst>::from_bits(unshifted << shift)
}
}
@ -218,7 +218,7 @@ macro_rules! bool_to_fixed {
#[inline]
fn from(src: bool) -> $DstI<FracDst> {
let unshifted = $DstI::<FracDst>::from_bits(src.into()).to_bits();
let shift = FracDst::to_u32();
let shift = FracDst::U32;
$DstI::<FracDst>::from_bits(unshifted << shift)
}
}

View File

@ -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();

View File

@ -265,14 +265,14 @@ macro_rules! pass_method {
#[doc = $comment]
#[inline]
pub fn $method() -> $Fixed<Frac> {
$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<Frac> {
$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<Frac> {
$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<Frac> {
$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<Frac> {
$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 {
<Self as SealedFixed>::INT_NBITS
Self::INT_NBITS
}
);
@ -509,7 +509,7 @@ assert_eq!(Fix::frac_bits(), 6);
),
#[inline]
pub fn frac_bits() -> u32 {
<Self as SealedFixed>::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) =
<<F as SealedFixed>::Bits as SealedInt>::to_fixed_overflow(
let (value, overflow) = F::Bits::to_fixed_overflow(
val.to_bits(),
F::FRAC_NBITS,
<$Fixed<Frac>>::FRAC_NBITS,
<$Fixed<Frac>>::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<Frac> as SealedFixed>::Bits) < 0 {
return $Fixed::max_value();
if (bits as <Self as SealedFixed>::Bits) < 0 {
return Self::max_value();
}
bits as _
bits as <Self as SealedFixed>::Bits
}
Widest::Negative(bits) => bits as _,
Widest::Negative(bits) => bits as <Self as SealedFixed>::Bits,
},
match value {
Widest::Unsigned(bits) => bits as _,
Widest::Negative(_) => return $Fixed::min_value(),
Widest::Unsigned(bits) => bits as <Self as SealedFixed>::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) =
<<F as SealedFixed>::Bits as SealedInt>::to_fixed_overflow(
let (value, mut overflow) = F::Bits::to_fixed_overflow(
val.to_bits(),
F::FRAC_NBITS,
<$Fixed<Frac>>::FRAC_NBITS,
<$Fixed<Frac>>::INT_NBITS,
Self::FRAC_NBITS,
Self::INT_NBITS,
);
let bits = if_signed_unsigned!(
$Signedness,
match value {
Widest::Unsigned(bits) => {
if (bits as <$Fixed<Frac> as SealedFixed>::Bits) < 0 {
if (bits as <Self as SealedFixed>::Bits) < 0 {
overflow = true;
}
bits as _
bits as <Self as SealedFixed>::Bits
}
Widest::Negative(bits) => bits as _,
Widest::Negative(bits) => bits as <Self as SealedFixed>::Bits,
},
match value {
Widest::Unsigned(bits) => bits as _,
Widest::Unsigned(bits) => bits as <Self as SealedFixed>::Bits,
Widest::Negative(bits) => {
overflow = true;
bits as _
bits as <Self as SealedFixed>::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) = <I as SealedInt>::to_fixed_overflow(
let (value, overflow) = I::to_fixed_overflow(
val,
0,
<$Fixed<Frac>>::FRAC_NBITS,
<$Fixed<Frac>>::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<Frac> as SealedFixed>::Bits) < 0 {
return $Fixed::max_value();
if (bits as <Self as SealedFixed>::Bits) < 0 {
return Self::max_value();
}
bits as _
bits as <Self as SealedFixed>::Bits
}
Widest::Negative(bits) => bits as _,
Widest::Negative(bits) => bits as <Self as SealedFixed>::Bits,
},
match value {
Widest::Unsigned(bits) => bits as _,
Widest::Negative(_) => return $Fixed::min_value(),
Widest::Unsigned(bits) => bits as <Self as SealedFixed>::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) = <I as SealedInt>::to_fixed_overflow(
let (value, mut overflow) = I::to_fixed_overflow(
val,
0,
<$Fixed<Frac>>::FRAC_NBITS,
<$Fixed<Frac>>::INT_NBITS,
Self::FRAC_NBITS,
Self::INT_NBITS,
);
let bits = if_signed_unsigned!(
$Signedness,
match value {
Widest::Unsigned(bits) => {
if (bits as <$Fixed<Frac> as SealedFixed>::Bits) < 0 {
if (bits as <Self as SealedFixed>::Bits) < 0 {
overflow = true;
}
bits as _
bits as <Self as SealedFixed>::Bits
}
Widest::Negative(bits) => bits as _,
Widest::Negative(bits) => bits as <Self as SealedFixed>::Bits,
},
match value {
Widest::Unsigned(bits) => bits as _,
Widest::Unsigned(bits) => bits as <Self as SealedFixed>::Bits,
Widest::Negative(bits) => {
overflow = true;
bits as _
bits as <Self as SealedFixed>::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>>::FRAC_NBITS < $nbits {
int >> <$Fixed<Frac>>::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) = <F as SealedFloat>::to_fixed_neg_abs_overflow(
let (neg, abs_128, overflow) = F::to_fixed_neg_abs_overflow(
val,
<$Fixed<Frac>>::FRAC_NBITS,
<$Fixed<Frac>>::INT_NBITS,
Self::FRAC_NBITS,
Self::INT_NBITS,
);
if overflow {
return saturated;
}
let abs_bits =
abs_128 as <<$Fixed<Frac> as SealedFixed>::Bits as SealedInt>::Unsigned;
let abs_bits = abs_128 as <<Self as SealedFixed>::Bits as SealedInt>::Unsigned;
if <<$Fixed<Frac> as SealedFixed>::Bits as SealedInt>::IS_SIGNED {
if <Self as SealedFixed>::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<Frac> as SealedFixed>::Bits as SealedInt>::Unsigned::MSB;
let msb = <<Self as SealedFixed>::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<Frac> as SealedFixed>::Bits;
} as <Self as SealedFixed>::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) =
<F as SealedFloat>::to_fixed_neg_abs_overflow(
let (neg, abs_128, mut overflow) = F::to_fixed_neg_abs_overflow(
val,
<$Fixed<Frac>>::FRAC_NBITS,
<$Fixed<Frac>>::INT_NBITS,
Self::FRAC_NBITS,
Self::INT_NBITS,
);
let abs_bits =
abs_128 as <<$Fixed<Frac> as SealedFixed>::Bits as SealedInt>::Unsigned;
let abs_bits = abs_128 as <<Self as SealedFixed>::Bits as SealedInt>::Unsigned;
if <<$Fixed<Frac> as SealedFixed>::Bits as SealedInt>::IS_SIGNED {
if <Self as SealedFixed>::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<Frac> as SealedFixed>::Bits as SealedInt>::Unsigned::MSB;
let msb = <<Self as SealedFixed>::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<Frac> as SealedFixed>::Bits;
} as <Self as SealedFixed>::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>>::FRAC_NBITS,
<$Fixed<Frac>>::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<Frac> {
$Fixed::from_bits(self.to_bits() & Self::int_mask())
let mask = Self::INT_MASK as <Self as SealedFixed>::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<Frac> {
$Fixed::from_bits(self.to_bits() & Self::frac_mask())
let mask = Self::FRAC_MASK as <Self as SealedFixed>::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<Frac> {
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<Frac> {
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(<Self as SealedFixed>::lowest_int_bit());
let int_lsb = Self::INT_LSB as <Self as SealedFixed>::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<Frac>, bool) {
let int = self.int();
let highest_frac_bit = <Self as SealedFixed>::highest_frac_bit();
if (self.to_bits() & highest_frac_bit) == 0 {
let frac_msb = Self::FRAC_MSB as <Self as SealedFixed>::Bits;
if (self.to_bits() & frac_msb) == 0 {
return (int, false);
}
let increment = Self::from_bits(<Self as SealedFixed>::lowest_int_bit());
let int_lsb = Self::INT_LSB as <Self as SealedFixed>::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<Frac>> {
<$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<Frac>) -> Option<$Fixed<Frac>> {
<$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<Frac>) -> Option<$Fixed<Frac>> {
<$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<Frac>) -> Option<$Fixed<Frac>> {
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<Frac>> {
<$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<Frac>> {
<$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<Frac>> {
<$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<Frac>> {
<$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<Frac>> {
<$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<Frac>> {
<$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<Frac>) -> $Fixed<Frac> {
$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<Frac>) -> $Fixed<Frac> {
$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<Frac>) -> $Fixed<Frac> {
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<Frac>) -> $Fixed<Frac> {
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<Frac> {
$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<Frac> {
$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<Frac>) -> $Fixed<Frac> {
$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<Frac>) -> $Fixed<Frac> {
$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<Frac>) -> $Fixed<Frac> {
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<Frac>) -> $Fixed<Frac> {
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<Frac> {
$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<Frac> {
$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<Frac> {
$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<Frac> {
$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<Frac> {
$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<Frac> {
$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<Frac>, 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<Frac>) -> ($Fixed<Frac>, 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<Frac>) -> ($Fixed<Frac>, 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<Frac>) -> ($Fixed<Frac>, 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<Frac>) -> ($Fixed<Frac>, 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<Frac>, 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<Frac>, 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<Frac>, 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<Frac>, 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<Frac>, 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<Frac>, 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<Frac>> {
<$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<Frac> {
match self.to_bits().cmp(&0) {
Ordering::Equal => $Fixed::from_bits(0),
Ordering::Greater => {
<$Fixed<Frac> as SealedFixed>::one().expect("overflow")
}
Ordering::Less => {
<$Fixed<Frac> 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"),
}
}
);

View File

@ -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<F>(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 {
<Self::Bits as SealedInt>::Unsigned,
<Self::Bits as SealedInt>::Unsigned,
) {
let frac_bits = <Self as SealedFixed>::FRAC_NBITS;
let int_bits = <Self as SealedFixed>::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)
}

View File

@ -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 = <Self::Bits as SealedInt>::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 = <Self::Bits as SealedInt>::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 = <Self::Bits as SealedInt>::NBITS;
let neg_mask = !0 << (nbits - 1);
let mant_mask = !(!0 << ($prec - 1));
let exp_mask = !(neg_mask | mant_mask);
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
fn is_sign_negative(self) -> bool {
(self.to_bits() & Self::SIGN_MASK) != 0
}
}) - <$Float as SealedFloat>::exp_bias();
let mant = bits & mant_mask;
#[inline]
#[cfg_attr(feature = "cargo-clippy", allow(clippy::cast_lossless))]
fn parts(self) -> (bool, i32, $Bits) {
let bits = self.to_bits();
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 {

View File

@ -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 = <Self as SealedInt>::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 = <Self as SealedInt>::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,

View File

@ -13,6 +13,8 @@
// <https://www.apache.org/licenses/LICENSE-2.0> and
// <https://opensource.org/licenses/MIT>.
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<U>: 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),
)
}
}