code cleanups
This commit is contained in:
parent
aa707df6c9
commit
f7d2fc18e0
190
src/arith.rs
190
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<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("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 {
|
||||
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("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::<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 &[
|
||||
|
|
34
src/cmp.rs
34
src/cmp.rs
|
@ -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)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
309
src/lib.rs
309
src/lib.rs
|
@ -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"),
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue