add Bits, from_bits, to_bits to Fixed trait; and add it to prelude
This commit is contained in:
parent
e9b256979b
commit
320147370f
30
src/cmp.rs
30
src/cmp.rs
|
@ -18,7 +18,7 @@ use half::f16;
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
frac::{IsLessOrEqual, True, Unsigned, U128, U16, U32, U64, U8},
|
frac::{IsLessOrEqual, True, Unsigned, U128, U16, U32, U64, U8},
|
||||||
sealed::{SealedFixed, SealedFloat, SealedInt, Widest},
|
sealed::{Fixed, SealedFixed, SealedFloat, SealedInt, Widest},
|
||||||
FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32, FixedU64,
|
FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32, FixedU64,
|
||||||
FixedU8,
|
FixedU8,
|
||||||
},
|
},
|
||||||
|
@ -40,8 +40,8 @@ macro_rules! fixed_cmp_fixed {
|
||||||
Self::INT_NBITS,
|
Self::INT_NBITS,
|
||||||
);
|
);
|
||||||
let rhs_bits = match rhs_128 {
|
let rhs_bits = match rhs_128 {
|
||||||
Widest::Unsigned(bits) => bits as <Self as SealedFixed>::Bits,
|
Widest::Unsigned(bits) => bits as <Self as Fixed>::Bits,
|
||||||
Widest::Negative(bits) => bits as <Self as SealedFixed>::Bits,
|
Widest::Negative(bits) => bits as <Self as Fixed>::Bits,
|
||||||
};
|
};
|
||||||
dir == Ordering::Equal && !overflow && rhs_bits == self.to_bits()
|
dir == Ordering::Equal && !overflow && rhs_bits == self.to_bits()
|
||||||
}
|
}
|
||||||
|
@ -72,8 +72,8 @@ macro_rules! fixed_cmp_fixed {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let rhs_bits = match rhs_128 {
|
let rhs_bits = match rhs_128 {
|
||||||
Widest::Unsigned(bits) => bits as <Self as SealedFixed>::Bits,
|
Widest::Unsigned(bits) => bits as <Self as Fixed>::Bits,
|
||||||
Widest::Negative(bits) => bits as <Self as SealedFixed>::Bits,
|
Widest::Negative(bits) => bits as <Self as Fixed>::Bits,
|
||||||
};
|
};
|
||||||
Some(self.to_bits().cmp(&rhs_bits).then(dir))
|
Some(self.to_bits().cmp(&rhs_bits).then(dir))
|
||||||
}
|
}
|
||||||
|
@ -94,8 +94,8 @@ macro_rules! fixed_cmp_fixed {
|
||||||
return !rhs.to_bits().is_negative();
|
return !rhs.to_bits().is_negative();
|
||||||
}
|
}
|
||||||
let rhs_bits = match rhs_128 {
|
let rhs_bits = match rhs_128 {
|
||||||
Widest::Unsigned(bits) => bits as <Self as SealedFixed>::Bits,
|
Widest::Unsigned(bits) => bits as <Self as Fixed>::Bits,
|
||||||
Widest::Negative(bits) => bits as <Self as SealedFixed>::Bits,
|
Widest::Negative(bits) => bits as <Self as Fixed>::Bits,
|
||||||
};
|
};
|
||||||
self.to_bits() < rhs_bits || (self.to_bits() == rhs_bits && dir == Ordering::Less)
|
self.to_bits() < rhs_bits || (self.to_bits() == rhs_bits && dir == Ordering::Less)
|
||||||
}
|
}
|
||||||
|
@ -216,8 +216,8 @@ macro_rules! fixed_cmp_float {
|
||||||
let (rhs_128, dir, overflow) =
|
let (rhs_128, dir, overflow) =
|
||||||
rhs.to_fixed_dir_overflow(Self::FRAC_NBITS, Self::INT_NBITS);
|
rhs.to_fixed_dir_overflow(Self::FRAC_NBITS, Self::INT_NBITS);
|
||||||
let rhs_bits = match rhs_128 {
|
let rhs_bits = match rhs_128 {
|
||||||
Widest::Unsigned(bits) => bits as <Self as SealedFixed>::Bits,
|
Widest::Unsigned(bits) => bits as <Self as Fixed>::Bits,
|
||||||
Widest::Negative(bits) => bits as <Self as SealedFixed>::Bits,
|
Widest::Negative(bits) => bits as <Self as Fixed>::Bits,
|
||||||
};
|
};
|
||||||
dir == Ordering::Equal && !overflow && rhs_bits == self.to_bits()
|
dir == Ordering::Equal && !overflow && rhs_bits == self.to_bits()
|
||||||
}
|
}
|
||||||
|
@ -265,8 +265,8 @@ macro_rules! fixed_cmp_float {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let rhs_bits = match rhs_128 {
|
let rhs_bits = match rhs_128 {
|
||||||
Widest::Unsigned(bits) => bits as <Self as SealedFixed>::Bits,
|
Widest::Unsigned(bits) => bits as <Self as Fixed>::Bits,
|
||||||
Widest::Negative(bits) => bits as <Self as SealedFixed>::Bits,
|
Widest::Negative(bits) => bits as <Self as Fixed>::Bits,
|
||||||
};
|
};
|
||||||
Some(self.to_bits().cmp(&rhs_bits).then(dir))
|
Some(self.to_bits().cmp(&rhs_bits).then(dir))
|
||||||
}
|
}
|
||||||
|
@ -291,8 +291,8 @@ macro_rules! fixed_cmp_float {
|
||||||
return !rhs_is_neg;
|
return !rhs_is_neg;
|
||||||
}
|
}
|
||||||
let rhs_bits = match rhs_128 {
|
let rhs_bits = match rhs_128 {
|
||||||
Widest::Unsigned(bits) => bits as <Self as SealedFixed>::Bits,
|
Widest::Unsigned(bits) => bits as <Self as Fixed>::Bits,
|
||||||
Widest::Negative(bits) => bits as <Self as SealedFixed>::Bits,
|
Widest::Negative(bits) => bits as <Self as Fixed>::Bits,
|
||||||
};
|
};
|
||||||
let lhs_bits = self.to_bits();
|
let lhs_bits = self.to_bits();
|
||||||
lhs_bits < rhs_bits || (lhs_bits == rhs_bits && dir == Ordering::Less)
|
lhs_bits < rhs_bits || (lhs_bits == rhs_bits && dir == Ordering::Less)
|
||||||
|
@ -343,8 +343,8 @@ macro_rules! fixed_cmp_float {
|
||||||
return lhs_is_neg;
|
return lhs_is_neg;
|
||||||
}
|
}
|
||||||
let lhs_bits = match lhs_128 {
|
let lhs_bits = match lhs_128 {
|
||||||
Widest::Unsigned(bits) => bits as <$Fix<Frac> as SealedFixed>::Bits,
|
Widest::Unsigned(bits) => bits as <$Fix<Frac> as Fixed>::Bits,
|
||||||
Widest::Negative(bits) => bits as <$Fix<Frac> as SealedFixed>::Bits,
|
Widest::Negative(bits) => bits as <$Fix<Frac> as Fixed>::Bits,
|
||||||
};
|
};
|
||||||
let rhs_bits = rhs.to_bits();
|
let rhs_bits = rhs.to_bits();
|
||||||
lhs_bits < rhs_bits || (lhs_bits == rhs_bits && dir == Ordering::Greater)
|
lhs_bits < rhs_bits || (lhs_bits == rhs_bits && dir == Ordering::Greater)
|
||||||
|
|
|
@ -148,7 +148,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fmt_radix2<F, Bits>(num: F, radix: &dyn Radix2, fmt: &mut Formatter) -> FmtResult
|
fn fmt_radix2<F, Bits>(num: F, radix: &dyn Radix2, fmt: &mut Formatter) -> FmtResult
|
||||||
where
|
where
|
||||||
F: SealedFixed<Bits = Bits>,
|
F: SealedFixed<SBits = Bits>,
|
||||||
Bits: SealedInt,
|
Bits: SealedInt,
|
||||||
Bits::Unsigned: FmtRadix2Helper,
|
Bits::Unsigned: FmtRadix2Helper,
|
||||||
{
|
{
|
||||||
|
@ -368,7 +368,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fmt_dec<F, Bits>(num: F, fmt: &mut Formatter) -> FmtResult
|
fn fmt_dec<F, Bits>(num: F, fmt: &mut Formatter) -> FmtResult
|
||||||
where
|
where
|
||||||
F: SealedFixed<Bits = Bits>,
|
F: SealedFixed<SBits = Bits>,
|
||||||
Bits: SealedInt,
|
Bits: SealedInt,
|
||||||
Bits::Unsigned: FmtDecHelper,
|
Bits::Unsigned: FmtDecHelper,
|
||||||
{
|
{
|
||||||
|
|
16
src/lib.rs
16
src/lib.rs
|
@ -224,11 +224,12 @@ use {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A "prelude" for users of the *fixed* crate.
|
/// A prelude for users of the *fixed* crate.
|
||||||
///
|
///
|
||||||
/// This prelude is similar to the standard library's prelude in that you'll
|
/// This prelude is similar to the [standard library’s
|
||||||
/// almost always want to import its entire contents, but unlike the standard
|
/// prelude][prelude] in that you’ll almost always want to import its
|
||||||
/// library's prelude you'll have to do so manually:
|
/// entire contents, but unlike the standard library’s prelude you’ll
|
||||||
|
/// have to do so manually:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// ##[allow(unused_imports)]
|
/// ##[allow(unused_imports)]
|
||||||
|
@ -236,8 +237,13 @@ use {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// The prelude may grow over time as additional items see ubiquitous use.
|
/// The prelude may grow over time as additional items see ubiquitous use.
|
||||||
|
///
|
||||||
|
/// [prelude]: https://doc.rust-lang.org/nightly/std/prelude/index.html
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::traits::{FromFixed, ToFixed};
|
pub use crate::{
|
||||||
|
sealed::Fixed,
|
||||||
|
traits::{FromFixed, ToFixed},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
@ -56,7 +56,7 @@ assert_eq!((-two_and_quarter).int(), -three);
|
||||||
";
|
";
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn int(self) -> $Fixed<Frac> {
|
pub fn int(self) -> $Fixed<Frac> {
|
||||||
let mask = Self::INT_MASK as <Self as SealedFixed>::Bits;
|
let mask = Self::INT_MASK as <Self as Fixed>::Bits;
|
||||||
Self::from_bits(self.to_bits() & mask)
|
Self::from_bits(self.to_bits() & mask)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -102,7 +102,7 @@ assert_eq!((-two_and_quarter).frac(), three_quarters);
|
||||||
";
|
";
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn frac(self) -> $Fixed<Frac> {
|
pub fn frac(self) -> $Fixed<Frac> {
|
||||||
let mask = Self::FRAC_MASK as <Self as SealedFixed>::Bits;
|
let mask = Self::FRAC_MASK as <Self as Fixed>::Bits;
|
||||||
Self::from_bits(self.to_bits() & mask)
|
Self::from_bits(self.to_bits() & mask)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -562,7 +562,7 @@ assert_eq!(two_half.overflowing_ceil(), (Fix::from_int(3), false));
|
||||||
if Self::INT_NBITS == 0 {
|
if Self::INT_NBITS == 0 {
|
||||||
return (int, self.to_bits() > 0);
|
return (int, self.to_bits() > 0);
|
||||||
}
|
}
|
||||||
let int_lsb = Self::INT_LSB as <Self as SealedFixed>::Bits;
|
let int_lsb = Self::INT_LSB as <Self as Fixed>::Bits;
|
||||||
let increment = Self::from_bits(int_lsb);
|
let increment = Self::from_bits(int_lsb);
|
||||||
if_signed! {
|
if_signed! {
|
||||||
$Signedness;
|
$Signedness;
|
||||||
|
@ -652,11 +652,11 @@ assert_eq!(two_half.overflowing_round(), (Fix::from_int(3), false));
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn overflowing_round(self) -> ($Fixed<Frac>, bool) {
|
pub fn overflowing_round(self) -> ($Fixed<Frac>, bool) {
|
||||||
let int = self.int();
|
let int = self.int();
|
||||||
let frac_msb = Self::FRAC_MSB as <Self as SealedFixed>::Bits;
|
let frac_msb = Self::FRAC_MSB as <Self as Fixed>::Bits;
|
||||||
if (self.to_bits() & frac_msb) == 0 {
|
if (self.to_bits() & frac_msb) == 0 {
|
||||||
return (int, false);
|
return (int, false);
|
||||||
}
|
}
|
||||||
let int_lsb = Self::INT_LSB as <Self as SealedFixed>::Bits;
|
let int_lsb = Self::INT_LSB as <Self as Fixed>::Bits;
|
||||||
let increment = Self::from_bits(int_lsb);
|
let increment = Self::from_bits(int_lsb);
|
||||||
if_signed! {
|
if_signed! {
|
||||||
$Signedness;
|
$Signedness;
|
||||||
|
|
119
src/sealed.rs
119
src/sealed.rs
|
@ -50,7 +50,7 @@ use half::f16;
|
||||||
/// [`u64`]: https://doc.rust-lang.org/nightly/std/primitive.u64.html
|
/// [`u64`]: https://doc.rust-lang.org/nightly/std/primitive.u64.html
|
||||||
/// [`u8`]: https://doc.rust-lang.org/nightly/std/primitive.u8.html
|
/// [`u8`]: https://doc.rust-lang.org/nightly/std/primitive.u8.html
|
||||||
/// [`usize`]: https://doc.rust-lang.org/nightly/std/primitive.usize.html
|
/// [`usize`]: https://doc.rust-lang.org/nightly/std/primitive.usize.html
|
||||||
pub trait Int: SealedInt + FromFixed + ToFixed {}
|
pub trait Int: SealedInt + FromFixed + ToFixed + Copy {}
|
||||||
|
|
||||||
/// This trait is implemented for the primitive floating-point types,
|
/// This trait is implemented for the primitive floating-point types,
|
||||||
/// and for [`f16`] if the [`f16` feature] is enabled.
|
/// and for [`f16`] if the [`f16` feature] is enabled.
|
||||||
|
@ -63,7 +63,7 @@ pub trait Int: SealedInt + FromFixed + ToFixed {}
|
||||||
/// [`f32`]: https://doc.rust-lang.org/nightly/std/primitive.f32.html
|
/// [`f32`]: https://doc.rust-lang.org/nightly/std/primitive.f32.html
|
||||||
/// [`f64`]: https://doc.rust-lang.org/nightly/std/primitive.f64.html
|
/// [`f64`]: https://doc.rust-lang.org/nightly/std/primitive.f64.html
|
||||||
/// [`f16` feature]: ../index.html#optional-features
|
/// [`f16` feature]: ../index.html#optional-features
|
||||||
pub trait Float: SealedFloat + FromFixed + ToFixed {}
|
pub trait Float: SealedFloat + FromFixed + ToFixed + Copy {}
|
||||||
|
|
||||||
/// This trait is implemented for all the fixed-point types.
|
/// This trait is implemented for all the fixed-point types.
|
||||||
///
|
///
|
||||||
|
@ -82,36 +82,16 @@ pub trait Float: SealedFloat + FromFixed + ToFixed {}
|
||||||
/// [`FixedU32`]: ../struct.FixedU32.html
|
/// [`FixedU32`]: ../struct.FixedU32.html
|
||||||
/// [`FixedU64`]: ../struct.FixedU64.html
|
/// [`FixedU64`]: ../struct.FixedU64.html
|
||||||
/// [`FixedU8`]: ../struct.FixedU8.html
|
/// [`FixedU8`]: ../struct.FixedU8.html
|
||||||
pub trait Fixed: SealedFixed + FromFixed + ToFixed {}
|
pub trait Fixed: SealedFixed + FromFixed + ToFixed + Copy {
|
||||||
|
/// The primitive integer underlying type.
|
||||||
|
type Bits: Int;
|
||||||
|
|
||||||
impl Int for i8 {}
|
/// Create with a given bit representation.
|
||||||
impl Int for i16 {}
|
fn from_bits(bits: Self::Bits) -> Self;
|
||||||
impl Int for i32 {}
|
|
||||||
impl Int for i64 {}
|
|
||||||
impl Int for i128 {}
|
|
||||||
impl Int for isize {}
|
|
||||||
impl Int for u8 {}
|
|
||||||
impl Int for u16 {}
|
|
||||||
impl Int for u32 {}
|
|
||||||
impl Int for u64 {}
|
|
||||||
impl Int for u128 {}
|
|
||||||
impl Int for usize {}
|
|
||||||
|
|
||||||
#[cfg(feature = "f16")]
|
/// Convert to a bit representation.
|
||||||
impl Float for f16 {}
|
fn to_bits(self) -> Self::Bits;
|
||||||
impl Float for f32 {}
|
}
|
||||||
impl Float for f64 {}
|
|
||||||
|
|
||||||
impl<Frac> Fixed for FixedI8<Frac> where Frac: Unsigned + IsLessOrEqual<U8, Output = True> {}
|
|
||||||
impl<Frac> Fixed for FixedI16<Frac> where Frac: Unsigned + IsLessOrEqual<U16, Output = True> {}
|
|
||||||
impl<Frac> Fixed for FixedI32<Frac> where Frac: Unsigned + IsLessOrEqual<U32, Output = True> {}
|
|
||||||
impl<Frac> Fixed for FixedI64<Frac> where Frac: Unsigned + IsLessOrEqual<U64, Output = True> {}
|
|
||||||
impl<Frac> Fixed for FixedI128<Frac> where Frac: Unsigned + IsLessOrEqual<U128, Output = True> {}
|
|
||||||
impl<Frac> Fixed for FixedU8<Frac> where Frac: Unsigned + IsLessOrEqual<U8, Output = True> {}
|
|
||||||
impl<Frac> Fixed for FixedU16<Frac> where Frac: Unsigned + IsLessOrEqual<U16, Output = True> {}
|
|
||||||
impl<Frac> Fixed for FixedU32<Frac> where Frac: Unsigned + IsLessOrEqual<U32, Output = True> {}
|
|
||||||
impl<Frac> Fixed for FixedU64<Frac> where Frac: Unsigned + IsLessOrEqual<U64, Output = True> {}
|
|
||||||
impl<Frac> Fixed for FixedU128<Frac> where Frac: Unsigned + IsLessOrEqual<U128, Output = True> {}
|
|
||||||
|
|
||||||
impl ToFixed for bool {
|
impl ToFixed for bool {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -151,8 +131,10 @@ impl ToFixed for bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! checked_int {
|
macro_rules! impl_int {
|
||||||
($Int:ty) => {
|
($Int:ident) => {
|
||||||
|
impl Int for $Int {}
|
||||||
|
|
||||||
impl FromFixed for $Int {
|
impl FromFixed for $Int {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_fixed<F>(val: F) -> Self
|
fn from_fixed<F>(val: F) -> Self
|
||||||
|
@ -231,21 +213,23 @@ macro_rules! checked_int {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
checked_int! { i8 }
|
impl_int! { i8 }
|
||||||
checked_int! { i16 }
|
impl_int! { i16 }
|
||||||
checked_int! { i32 }
|
impl_int! { i32 }
|
||||||
checked_int! { i64 }
|
impl_int! { i64 }
|
||||||
checked_int! { i128 }
|
impl_int! { i128 }
|
||||||
checked_int! { isize }
|
impl_int! { isize }
|
||||||
checked_int! { u8 }
|
impl_int! { u8 }
|
||||||
checked_int! { u16 }
|
impl_int! { u16 }
|
||||||
checked_int! { u32 }
|
impl_int! { u32 }
|
||||||
checked_int! { u64 }
|
impl_int! { u64 }
|
||||||
checked_int! { u128 }
|
impl_int! { u128 }
|
||||||
checked_int! { usize }
|
impl_int! { usize }
|
||||||
|
|
||||||
macro_rules! checked_float {
|
macro_rules! impl_float {
|
||||||
($Float:ty) => {
|
($Float:ty) => {
|
||||||
|
impl Float for $Float {}
|
||||||
|
|
||||||
impl FromFixed for $Float {
|
impl FromFixed for $Float {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_fixed<F>(val: F) -> Self
|
fn from_fixed<F>(val: F) -> Self
|
||||||
|
@ -325,12 +309,27 @@ macro_rules! checked_float {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "f16")]
|
#[cfg(feature = "f16")]
|
||||||
checked_float! { f16 }
|
impl_float! { f16 }
|
||||||
checked_float! { f32 }
|
impl_float! { f32 }
|
||||||
checked_float! { f64 }
|
impl_float! { f64 }
|
||||||
|
|
||||||
|
macro_rules! impl_fixed {
|
||||||
|
($Fixed:ident, $NBits:ident, $Bits:ident) => {
|
||||||
|
impl<Frac> Fixed for $Fixed<Frac>
|
||||||
|
where
|
||||||
|
Frac: Unsigned + IsLessOrEqual<$NBits, Output = True>,
|
||||||
|
{
|
||||||
|
type Bits = $Bits;
|
||||||
|
#[inline]
|
||||||
|
fn from_bits(bits: Self::Bits) -> Self {
|
||||||
|
$Fixed::from_bits(bits)
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn to_bits(self) -> Self::Bits {
|
||||||
|
self.to_bits()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! checked_fixed {
|
|
||||||
($Fixed:ident, $NBits:ident) => {
|
|
||||||
impl<Frac> FromFixed for $Fixed<Frac>
|
impl<Frac> FromFixed for $Fixed<Frac>
|
||||||
where
|
where
|
||||||
Frac: Unsigned + IsLessOrEqual<$NBits, Output = True>,
|
Frac: Unsigned + IsLessOrEqual<$NBits, Output = True>,
|
||||||
|
@ -415,13 +414,13 @@ macro_rules! checked_fixed {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
checked_fixed! { FixedI8, U8 }
|
impl_fixed! { FixedI8, U8, i8 }
|
||||||
checked_fixed! { FixedI16, U16 }
|
impl_fixed! { FixedI16, U16, i16 }
|
||||||
checked_fixed! { FixedI32, U32 }
|
impl_fixed! { FixedI32, U32, i32 }
|
||||||
checked_fixed! { FixedI64, U64 }
|
impl_fixed! { FixedI64, U64, i64 }
|
||||||
checked_fixed! { FixedI128, U128 }
|
impl_fixed! { FixedI128, U128, i128 }
|
||||||
checked_fixed! { FixedU8, U8 }
|
impl_fixed! { FixedU8, U8, u8 }
|
||||||
checked_fixed! { FixedU16, U16 }
|
impl_fixed! { FixedU16, U16, u16 }
|
||||||
checked_fixed! { FixedU32, U32 }
|
impl_fixed! { FixedU32, U32, u32 }
|
||||||
checked_fixed! { FixedU64, U64 }
|
impl_fixed! { FixedU64, U64, u64 }
|
||||||
checked_fixed! { FixedU128, U128 }
|
impl_fixed! { FixedU128, U128, u128 }
|
||||||
|
|
|
@ -35,10 +35,10 @@ pub enum Widest {
|
||||||
|
|
||||||
pub trait SealedFixed: Copy + Debug + Default + Display + Eq + Hash + Ord {
|
pub trait SealedFixed: Copy + Debug + Default + Display + Eq + Hash + Ord {
|
||||||
type FracNBits: Unsigned;
|
type FracNBits: Unsigned;
|
||||||
type Bits: SealedInt;
|
type SBits: SealedInt;
|
||||||
|
|
||||||
const FRAC_NBITS: u32 = Self::FracNBits::U32;
|
const FRAC_NBITS: u32 = Self::FracNBits::U32;
|
||||||
const INT_NBITS: u32 = Self::Bits::NBITS - Self::FRAC_NBITS;
|
const INT_NBITS: u32 = Self::SBits::NBITS - Self::FRAC_NBITS;
|
||||||
|
|
||||||
const FRAC_MASK: u128 = !Self::INT_MASK;
|
const FRAC_MASK: u128 = !Self::INT_MASK;
|
||||||
// split shift in two parts in case that FRAC_NBITS == 128
|
// split shift in two parts in case that FRAC_NBITS == 128
|
||||||
|
@ -96,31 +96,33 @@ pub trait SealedFixed: Copy + Debug + Default + Display + Eq + Hash + Ord {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn one() -> Option<Self> {
|
fn one() -> Option<Self> {
|
||||||
let min_int_bits = if Self::Bits::IS_SIGNED { 2 } else { 1 };
|
let min_int_bits = if Self::SBits::IS_SIGNED { 2 } else { 1 };
|
||||||
if Self::INT_NBITS < min_int_bits {
|
if Self::INT_NBITS < min_int_bits {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(Self::from_bits(Self::Bits::one_shl(Self::FRAC_NBITS)))
|
Some(Self::from_sbits(Self::SBits::one_shl(Self::FRAC_NBITS)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn minus_one() -> Option<Self> {
|
fn minus_one() -> Option<Self> {
|
||||||
if !Self::Bits::IS_SIGNED || Self::INT_NBITS < 1 {
|
if !Self::SBits::IS_SIGNED || Self::INT_NBITS < 1 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(Self::from_bits(Self::Bits::all_ones_shl(Self::FRAC_NBITS)))
|
Some(Self::from_sbits(Self::SBits::all_ones_shl(
|
||||||
|
Self::FRAC_NBITS,
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_bits(bits: Self::Bits) -> Self;
|
fn from_sbits(bits: Self::SBits) -> Self;
|
||||||
fn to_bits(self) -> Self::Bits;
|
fn to_sbits(self) -> Self::SBits;
|
||||||
fn parts(
|
fn parts(
|
||||||
self,
|
self,
|
||||||
) -> (
|
) -> (
|
||||||
bool,
|
bool,
|
||||||
<Self::Bits as SealedInt>::Unsigned,
|
<Self::SBits as SealedInt>::Unsigned,
|
||||||
<Self::Bits as SealedInt>::Unsigned,
|
<Self::SBits as SealedInt>::Unsigned,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn wrapping_ceil(self) -> Self;
|
fn wrapping_ceil(self) -> Self;
|
||||||
|
@ -137,7 +139,7 @@ macro_rules! sealed_fixed {
|
||||||
Frac: Unsigned + IsLessOrEqual<$Len, Output = True>,
|
Frac: Unsigned + IsLessOrEqual<$Len, Output = True>,
|
||||||
{
|
{
|
||||||
type FracNBits = Frac;
|
type FracNBits = Frac;
|
||||||
type Bits = $Bits;
|
type SBits = $Bits;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn saturating_from_fixed<F>(val: F) -> Self
|
fn saturating_from_fixed<F>(val: F) -> Self
|
||||||
|
@ -151,30 +153,30 @@ macro_rules! sealed_fixed {
|
||||||
);
|
);
|
||||||
if overflow {
|
if overflow {
|
||||||
return if val.to_bits().is_negative() {
|
return if val.to_bits().is_negative() {
|
||||||
Self::from_bits(Self::Bits::min_value())
|
Fixed::from_bits(Self::SBits::min_value())
|
||||||
} else {
|
} else {
|
||||||
Self::from_bits(Self::Bits::max_value())
|
Fixed::from_bits(Self::SBits::max_value())
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let bits = if_signed_unsigned!(
|
let bits = if_signed_unsigned!(
|
||||||
$Signedness,
|
$Signedness,
|
||||||
match value {
|
match value {
|
||||||
Widest::Unsigned(bits) => {
|
Widest::Unsigned(bits) => {
|
||||||
if (bits as Self::Bits) < 0 {
|
if (bits as Self::SBits) < 0 {
|
||||||
return Self::from_bits(Self::Bits::max_value());
|
return Fixed::from_bits(Self::SBits::max_value());
|
||||||
}
|
}
|
||||||
bits as Self::Bits
|
bits as Self::SBits
|
||||||
}
|
}
|
||||||
Widest::Negative(bits) => bits as Self::Bits,
|
Widest::Negative(bits) => bits as Self::SBits,
|
||||||
},
|
},
|
||||||
match value {
|
match value {
|
||||||
Widest::Unsigned(bits) => bits as Self::Bits,
|
Widest::Unsigned(bits) => bits as Self::SBits,
|
||||||
Widest::Negative(_) => {
|
Widest::Negative(_) => {
|
||||||
return Self::from_bits(Self::Bits::min_value());
|
return Fixed::from_bits(Self::SBits::min_value());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
SealedFixed::from_bits(bits)
|
Fixed::from_bits(bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -191,22 +193,22 @@ macro_rules! sealed_fixed {
|
||||||
$Signedness,
|
$Signedness,
|
||||||
match value {
|
match value {
|
||||||
Widest::Unsigned(bits) => {
|
Widest::Unsigned(bits) => {
|
||||||
if (bits as Self::Bits) < 0 {
|
if (bits as Self::SBits) < 0 {
|
||||||
overflow = true;
|
overflow = true;
|
||||||
}
|
}
|
||||||
bits as Self::Bits
|
bits as Self::SBits
|
||||||
}
|
}
|
||||||
Widest::Negative(bits) => bits as Self::Bits,
|
Widest::Negative(bits) => bits as Self::SBits,
|
||||||
},
|
},
|
||||||
match value {
|
match value {
|
||||||
Widest::Unsigned(bits) => bits as Self::Bits,
|
Widest::Unsigned(bits) => bits as Self::SBits,
|
||||||
Widest::Negative(bits) => {
|
Widest::Negative(bits) => {
|
||||||
overflow = true;
|
overflow = true;
|
||||||
bits as Self::Bits
|
bits as Self::SBits
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
(SealedFixed::from_bits(bits), overflow)
|
(Fixed::from_bits(bits), overflow)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -234,19 +236,19 @@ macro_rules! sealed_fixed {
|
||||||
$Signedness,
|
$Signedness,
|
||||||
match value {
|
match value {
|
||||||
Widest::Unsigned(bits) => {
|
Widest::Unsigned(bits) => {
|
||||||
if (bits as <Self as SealedFixed>::Bits) < 0 {
|
if (bits as Self::SBits) < 0 {
|
||||||
return Self::max_value();
|
return Self::max_value();
|
||||||
}
|
}
|
||||||
bits as <Self as SealedFixed>::Bits
|
bits as Self::SBits
|
||||||
}
|
}
|
||||||
Widest::Negative(bits) => bits as <Self as SealedFixed>::Bits,
|
Widest::Negative(bits) => bits as Self::SBits,
|
||||||
},
|
},
|
||||||
match value {
|
match value {
|
||||||
Widest::Unsigned(bits) => bits as <Self as SealedFixed>::Bits,
|
Widest::Unsigned(bits) => bits as Self::SBits,
|
||||||
Widest::Negative(_) => return Self::min_value(),
|
Widest::Negative(_) => return Self::min_value(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
SealedFixed::from_bits(bits)
|
Fixed::from_bits(bits)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn overflowing_from_float<F>(val: F) -> (Self, bool)
|
fn overflowing_from_float<F>(val: F) -> (Self, bool)
|
||||||
|
@ -262,22 +264,22 @@ macro_rules! sealed_fixed {
|
||||||
$Signedness,
|
$Signedness,
|
||||||
match value {
|
match value {
|
||||||
Widest::Unsigned(bits) => {
|
Widest::Unsigned(bits) => {
|
||||||
if (bits as <Self as SealedFixed>::Bits) < 0 {
|
if (bits as Self::SBits) < 0 {
|
||||||
overflow = true;
|
overflow = true;
|
||||||
}
|
}
|
||||||
bits as <Self as SealedFixed>::Bits
|
bits as Self::SBits
|
||||||
}
|
}
|
||||||
Widest::Negative(bits) => bits as <Self as SealedFixed>::Bits,
|
Widest::Negative(bits) => bits as Self::SBits,
|
||||||
},
|
},
|
||||||
match value {
|
match value {
|
||||||
Widest::Unsigned(bits) => bits as <Self as SealedFixed>::Bits,
|
Widest::Unsigned(bits) => bits as Self::SBits,
|
||||||
Widest::Negative(bits) => {
|
Widest::Negative(bits) => {
|
||||||
overflow = true;
|
overflow = true;
|
||||||
bits as <Self as SealedFixed>::Bits
|
bits as Self::SBits
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
(SealedFixed::from_bits(bits), overflow)
|
(Fixed::from_bits(bits), overflow)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -290,12 +292,12 @@ macro_rules! sealed_fixed {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_bits(bits: Self::Bits) -> Self {
|
fn from_sbits(bits: Self::SBits) -> Self {
|
||||||
$Fixed::from_bits(bits)
|
$Fixed::from_bits(bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_bits(self) -> Self::Bits {
|
fn to_sbits(self) -> Self::SBits {
|
||||||
$Fixed::to_bits(self)
|
$Fixed::to_bits(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,8 +306,8 @@ macro_rules! sealed_fixed {
|
||||||
self,
|
self,
|
||||||
) -> (
|
) -> (
|
||||||
bool,
|
bool,
|
||||||
<Self::Bits as SealedInt>::Unsigned,
|
<Self::SBits as SealedInt>::Unsigned,
|
||||||
<Self::Bits as SealedInt>::Unsigned,
|
<Self::SBits as SealedInt>::Unsigned,
|
||||||
) {
|
) {
|
||||||
let (neg, abs) = SealedInt::neg_abs(self.to_bits());
|
let (neg, abs) = SealedInt::neg_abs(self.to_bits());
|
||||||
let (int_abs, frac_abs) = if Self::INT_NBITS == 0 {
|
let (int_abs, frac_abs) = if Self::INT_NBITS == 0 {
|
||||||
|
|
Loading…
Reference in New Issue