constify some stuff
This commit is contained in:
parent
87b00f66a2
commit
aa707df6c9
|
@ -82,7 +82,7 @@ macro_rules! fmt_radix2_helper {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn take_frac_digit(&mut self, digit_bits: u32) -> u8 {
|
fn take_frac_digit(&mut self, digit_bits: u32) -> u8 {
|
||||||
let nbits = <$UInner as SealedInt>::nbits();
|
let nbits = <$UInner as SealedInt>::NBITS;
|
||||||
let rem_bits = nbits - digit_bits;
|
let rem_bits = nbits - digit_bits;
|
||||||
let mask = !0 << rem_bits;
|
let mask = !0 << rem_bits;
|
||||||
let ret = ((*self & mask) >> rem_bits) as u8;
|
let ret = ((*self & mask) >> rem_bits) as u8;
|
||||||
|
@ -104,7 +104,7 @@ fn fmt_radix2_helper<F>(
|
||||||
where
|
where
|
||||||
F: FmtRadix2Helper,
|
F: FmtRadix2Helper,
|
||||||
{
|
{
|
||||||
let int_bits = F::nbits() - frac_bits;
|
let int_bits = F::NBITS - frac_bits;
|
||||||
let digit_bits: u32 = radix.digit_bits();
|
let digit_bits: u32 = radix.digit_bits();
|
||||||
// 128 binary digits, one radix point, one leading zero
|
// 128 binary digits, one radix point, one leading zero
|
||||||
let mut buf: [u8; 130] = [0; 130];
|
let mut buf: [u8; 130] = [0; 130];
|
||||||
|
@ -150,7 +150,7 @@ where
|
||||||
Bits: SealedInt,
|
Bits: SealedInt,
|
||||||
Bits::Unsigned: FmtRadix2Helper,
|
Bits::Unsigned: FmtRadix2Helper,
|
||||||
{
|
{
|
||||||
fmt_radix2_helper(F::frac_bits(), num.parts(), radix, fmt)
|
fmt_radix2_helper(F::FRAC_NBITS, num.parts(), radix, fmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_fmt {
|
macro_rules! impl_fmt {
|
||||||
|
@ -252,7 +252,7 @@ macro_rules! fmt_dec_helper {
|
||||||
impl FmtDecHelper for $UInner {
|
impl FmtDecHelper for $UInner {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn cmp_half(&self) -> Ordering {
|
fn cmp_half(&self) -> Ordering {
|
||||||
self.cmp(&<$UInner as SealedInt>::msb())
|
self.cmp(&<$UInner as SealedInt>::MSB)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -283,7 +283,7 @@ fn fmt_dec_helper<F>(
|
||||||
where
|
where
|
||||||
F: FmtDecHelper,
|
F: FmtDecHelper,
|
||||||
{
|
{
|
||||||
let int_bits = F::nbits() - frac_bits;
|
let int_bits = F::NBITS - frac_bits;
|
||||||
// 40 int digits
|
// 40 int digits
|
||||||
// + 128 frac digits
|
// + 128 frac digits
|
||||||
// + 1 dec point,
|
// + 1 dec point,
|
||||||
|
@ -332,7 +332,7 @@ where
|
||||||
*r = b'0' + frac.take_frac_digit();
|
*r = b'0' + frac.take_frac_digit();
|
||||||
}
|
}
|
||||||
// check for rounding up
|
// check for rounding up
|
||||||
let round_up = match frac.cmp(&F::msb()) {
|
let round_up = match frac.cmp(&F::MSB) {
|
||||||
Ordering::Less => false,
|
Ordering::Less => false,
|
||||||
Ordering::Greater => true,
|
Ordering::Greater => true,
|
||||||
Ordering::Equal => {
|
Ordering::Equal => {
|
||||||
|
@ -370,7 +370,7 @@ where
|
||||||
Bits: SealedInt,
|
Bits: SealedInt,
|
||||||
Bits::Unsigned: FmtDecHelper,
|
Bits::Unsigned: FmtDecHelper,
|
||||||
{
|
{
|
||||||
fmt_dec_helper(F::frac_bits(), num.parts(), fmt)
|
fmt_dec_helper(F::FRAC_NBITS, num.parts(), fmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -19,6 +19,7 @@ This module reexports items from the [*typenum* crate].
|
||||||
[*typenum* crate]: https://crates.io/crates/typenum
|
[*typenum* crate]: https://crates.io/crates/typenum
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
pub(crate) use typenum::{Bit, False};
|
||||||
pub use typenum::{
|
pub use typenum::{
|
||||||
IsGreaterOrEqual, IsLessOrEqual, True, Unsigned, U0, U1, U10, U100, U101, U102, U103, U104,
|
IsGreaterOrEqual, IsLessOrEqual, True, Unsigned, U0, U1, U10, U100, U101, U102, U103, U104,
|
||||||
U105, U106, U107, U108, U109, U11, U110, U111, U112, U113, U114, U115, U116, U117, U118, U119,
|
U105, U106, U107, U108, U109, U11, U110, U111, U112, U113, U114, U115, U116, U117, U118, U119,
|
||||||
|
|
83
src/lib.rs
83
src/lib.rs
|
@ -487,7 +487,7 @@ assert_eq!(Fix::int_bits(), ",
|
||||||
),
|
),
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn int_bits() -> u32 {
|
pub fn int_bits() -> u32 {
|
||||||
<Self as SealedFixed>::int_bits()
|
<Self as SealedFixed>::INT_NBITS
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -509,7 +509,7 @@ assert_eq!(Fix::frac_bits(), 6);
|
||||||
),
|
),
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn frac_bits() -> u32 {
|
pub fn frac_bits() -> u32 {
|
||||||
<Self as SealedFixed>::frac_bits()
|
<Self as SealedFixed>::FRAC_NBITS
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -730,15 +730,12 @@ assert_eq!(Fix::saturating_from_fixed(too_small), Fix::min_value());
|
||||||
where
|
where
|
||||||
F: Fixed,
|
F: Fixed,
|
||||||
{
|
{
|
||||||
let frac_bits = Self::frac_bits();
|
|
||||||
let int_bits = Self::int_bits();
|
|
||||||
|
|
||||||
let (value, overflow) =
|
let (value, overflow) =
|
||||||
<<F as SealedFixed>::Bits as SealedInt>::to_fixed_overflow(
|
<<F as SealedFixed>::Bits as SealedInt>::to_fixed_overflow(
|
||||||
val.to_bits(),
|
val.to_bits(),
|
||||||
<F as SealedFixed>::frac_bits(),
|
F::FRAC_NBITS,
|
||||||
frac_bits,
|
<$Fixed<Frac>>::FRAC_NBITS,
|
||||||
int_bits,
|
<$Fixed<Frac>>::FRAC_NBITS,
|
||||||
);
|
);
|
||||||
if overflow {
|
if overflow {
|
||||||
return if val.to_bits().neg_abs().0 {
|
return if val.to_bits().neg_abs().0 {
|
||||||
|
@ -870,15 +867,12 @@ assert_eq!(Fix::overflowing_from_fixed(large), (wrapped, true));
|
||||||
where
|
where
|
||||||
F: Fixed,
|
F: Fixed,
|
||||||
{
|
{
|
||||||
let frac_bits = Self::frac_bits();
|
|
||||||
let int_bits = Self::int_bits();
|
|
||||||
|
|
||||||
let (value, mut overflow) =
|
let (value, mut overflow) =
|
||||||
<<F as SealedFixed>::Bits as SealedInt>::to_fixed_overflow(
|
<<F as SealedFixed>::Bits as SealedInt>::to_fixed_overflow(
|
||||||
val.to_bits(),
|
val.to_bits(),
|
||||||
<F as SealedFixed>::frac_bits(),
|
F::FRAC_NBITS,
|
||||||
frac_bits,
|
<$Fixed<Frac>>::FRAC_NBITS,
|
||||||
int_bits,
|
<$Fixed<Frac>>::INT_NBITS,
|
||||||
);
|
);
|
||||||
let bits = if_signed_unsigned!(
|
let bits = if_signed_unsigned!(
|
||||||
$Signedness,
|
$Signedness,
|
||||||
|
@ -1145,11 +1139,12 @@ assert_eq!(Fix::saturating_from_int(too_small), Fix::min_value());
|
||||||
where
|
where
|
||||||
I: Int,
|
I: Int,
|
||||||
{
|
{
|
||||||
let frac_bits = Self::frac_bits();
|
let (value, overflow) = <I as SealedInt>::to_fixed_overflow(
|
||||||
let int_bits = Self::int_bits();
|
val,
|
||||||
|
0,
|
||||||
let (value, overflow) =
|
<$Fixed<Frac>>::FRAC_NBITS,
|
||||||
<I as SealedInt>::to_fixed_overflow(val, 0, frac_bits, int_bits);
|
<$Fixed<Frac>>::INT_NBITS,
|
||||||
|
);
|
||||||
if overflow {
|
if overflow {
|
||||||
return if val.neg_abs().0 {
|
return if val.neg_abs().0 {
|
||||||
$Fixed::min_value()
|
$Fixed::min_value()
|
||||||
|
@ -1293,11 +1288,12 @@ assert_eq!(Fix::overflowing_from_int(large), (wrapped, true));
|
||||||
where
|
where
|
||||||
I: Int,
|
I: Int,
|
||||||
{
|
{
|
||||||
let frac_bits = Self::frac_bits();
|
let (value, mut overflow) = <I as SealedInt>::to_fixed_overflow(
|
||||||
let int_bits = Self::int_bits();
|
val,
|
||||||
|
0,
|
||||||
let (value, mut overflow) =
|
<$Fixed<Frac>>::FRAC_NBITS,
|
||||||
<I as SealedInt>::to_fixed_overflow(val, 0, frac_bits, int_bits);
|
<$Fixed<Frac>>::INT_NBITS,
|
||||||
|
);
|
||||||
let bits = if_signed_unsigned!(
|
let bits = if_signed_unsigned!(
|
||||||
$Signedness,
|
$Signedness,
|
||||||
match value {
|
match value {
|
||||||
|
@ -1359,8 +1355,8 @@ assert_eq!((-two_half).to_int(), -3);",
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_int(self) -> $Inner {
|
pub fn to_int(self) -> $Inner {
|
||||||
let int = self.int().to_bits();
|
let int = self.int().to_bits();
|
||||||
if Self::frac_bits() < $nbits {
|
if <$Fixed<Frac>>::FRAC_NBITS < $nbits {
|
||||||
int >> Self::frac_bits()
|
int >> <$Fixed<Frac>>::FRAC_NBITS
|
||||||
} else {
|
} else {
|
||||||
int
|
int
|
||||||
}
|
}
|
||||||
|
@ -1548,8 +1544,6 @@ assert_eq!(Fix::saturating_from_float(f64::NEG_INFINITY), Fix::min_value());
|
||||||
where
|
where
|
||||||
F: Float,
|
F: Float,
|
||||||
{
|
{
|
||||||
let frac_bits = Self::frac_bits();
|
|
||||||
let int_bits = Self::int_bits();
|
|
||||||
let saturated = if val.is_sign_positive() {
|
let saturated = if val.is_sign_positive() {
|
||||||
$Fixed::max_value()
|
$Fixed::max_value()
|
||||||
} else {
|
} else {
|
||||||
|
@ -1558,19 +1552,22 @@ assert_eq!(Fix::saturating_from_float(f64::NEG_INFINITY), Fix::min_value());
|
||||||
if !val.is_finite() {
|
if !val.is_finite() {
|
||||||
return saturated;
|
return saturated;
|
||||||
}
|
}
|
||||||
let (neg, abs_128, overflow) =
|
let (neg, abs_128, overflow) = <F as SealedFloat>::to_fixed_neg_abs_overflow(
|
||||||
<F as SealedFloat>::to_fixed_neg_abs_overflow(val, frac_bits, int_bits);
|
val,
|
||||||
|
<$Fixed<Frac>>::FRAC_NBITS,
|
||||||
|
<$Fixed<Frac>>::INT_NBITS,
|
||||||
|
);
|
||||||
if overflow {
|
if overflow {
|
||||||
return saturated;
|
return saturated;
|
||||||
}
|
}
|
||||||
let abs_bits =
|
let abs_bits =
|
||||||
abs_128 as <<$Fixed<Frac> as SealedFixed>::Bits as SealedInt>::Unsigned;
|
abs_128 as <<$Fixed<Frac> as SealedFixed>::Bits as SealedInt>::Unsigned;
|
||||||
|
|
||||||
if <<$Fixed<Frac> as SealedFixed>::Bits as SealedInt>::is_signed() {
|
if <<$Fixed<Frac> as SealedFixed>::Bits as SealedInt>::IS_SIGNED {
|
||||||
// most significant bit (msb) can be one only for min value,
|
// most significant bit (msb) can be one only for min value,
|
||||||
// that is for a negative value with only the msb true.
|
// that is for a negative value with only the msb true.
|
||||||
let msb =
|
let msb =
|
||||||
<<$Fixed<Frac> as SealedFixed>::Bits as SealedInt>::Unsigned::msb();
|
<<$Fixed<Frac> as SealedFixed>::Bits as SealedInt>::Unsigned::MSB;
|
||||||
if abs_bits & msb != 0 {
|
if abs_bits & msb != 0 {
|
||||||
if !neg || abs_bits != msb {
|
if !neg || abs_bits != msb {
|
||||||
return saturated;
|
return saturated;
|
||||||
|
@ -1710,22 +1707,23 @@ assert_eq!(Fix::overflowing_from_float(large), (wrapped, true));
|
||||||
where
|
where
|
||||||
F: Float,
|
F: Float,
|
||||||
{
|
{
|
||||||
let frac_bits = Self::frac_bits();
|
|
||||||
let int_bits = Self::int_bits();
|
|
||||||
|
|
||||||
if !val.is_finite() {
|
if !val.is_finite() {
|
||||||
panic!("{} is not finite", val);
|
panic!("{} is not finite", val);
|
||||||
}
|
}
|
||||||
let (neg, abs_128, mut overflow) =
|
let (neg, abs_128, mut overflow) =
|
||||||
<F as SealedFloat>::to_fixed_neg_abs_overflow(val, frac_bits, int_bits);
|
<F as SealedFloat>::to_fixed_neg_abs_overflow(
|
||||||
|
val,
|
||||||
|
<$Fixed<Frac>>::FRAC_NBITS,
|
||||||
|
<$Fixed<Frac>>::INT_NBITS,
|
||||||
|
);
|
||||||
let abs_bits =
|
let abs_bits =
|
||||||
abs_128 as <<$Fixed<Frac> as SealedFixed>::Bits as SealedInt>::Unsigned;
|
abs_128 as <<$Fixed<Frac> as SealedFixed>::Bits as SealedInt>::Unsigned;
|
||||||
|
|
||||||
if <<$Fixed<Frac> as SealedFixed>::Bits as SealedInt>::is_signed() {
|
if <<$Fixed<Frac> as SealedFixed>::Bits as SealedInt>::IS_SIGNED {
|
||||||
// most significant bit (msb) can be one only for min value,
|
// most significant bit (msb) can be one only for min value,
|
||||||
// that is for a negative value with only the msb true.
|
// that is for a negative value with only the msb true.
|
||||||
let msb =
|
let msb =
|
||||||
<<$Fixed<Frac> as SealedFixed>::Bits as SealedInt>::Unsigned::msb();
|
<<$Fixed<Frac> as SealedFixed>::Bits as SealedInt>::Unsigned::MSB;
|
||||||
if abs_bits & msb != 0 {
|
if abs_bits & msb != 0 {
|
||||||
if !neg || abs_bits != msb {
|
if !neg || abs_bits != msb {
|
||||||
overflow = true;
|
overflow = true;
|
||||||
|
@ -1782,10 +1780,13 @@ assert_eq!(Fix::from_bits(",
|
||||||
where
|
where
|
||||||
F: Float,
|
F: Float,
|
||||||
{
|
{
|
||||||
let frac_bits = Self::frac_bits();
|
|
||||||
let int_bits = Self::int_bits();
|
|
||||||
let (neg, abs) = self.to_bits().neg_abs();
|
let (neg, abs) = self.to_bits().neg_abs();
|
||||||
SealedFloat::from_neg_abs(neg, u128::from(abs), frac_bits, int_bits)
|
SealedFloat::from_neg_abs(
|
||||||
|
neg,
|
||||||
|
u128::from(abs),
|
||||||
|
<$Fixed<Frac>>::FRAC_NBITS,
|
||||||
|
<$Fixed<Frac>>::INT_NBITS,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -29,13 +29,18 @@ pub enum Widest {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SealedFixed: Copy + Debug + Display {
|
pub trait SealedFixed: Copy + Debug + Display {
|
||||||
|
type FracNBits: Unsigned;
|
||||||
type Bits: SealedInt;
|
type Bits: SealedInt;
|
||||||
type Frac: Unsigned;
|
|
||||||
|
|
||||||
fn frac_bits() -> u32;
|
const FRAC_NBITS: u32 = Self::FracNBits::U32;
|
||||||
fn int_bits() -> u32 {
|
const INT_NBITS: u32 = Self::Bits::NBITS - Self::FRAC_NBITS;
|
||||||
Self::Bits::nbits() - Self::frac_bits()
|
|
||||||
}
|
const FRAC_MASK: u128 = !Self::INT_MASK;
|
||||||
|
// 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);
|
||||||
|
|
||||||
fn from_fixed<F>(fixed: F) -> Self
|
fn from_fixed<F>(fixed: F) -> Self
|
||||||
where
|
where
|
||||||
|
@ -43,20 +48,20 @@ pub trait SealedFixed: Copy + Debug + Display {
|
||||||
|
|
||||||
#[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::Bits::IS_SIGNED { 2 } else { 1 };
|
||||||
if Self::int_bits() < min_int_bits {
|
if Self::INT_NBITS < min_int_bits {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(Self::from_bits(Self::Bits::one_shl(Self::frac_bits())))
|
Some(Self::from_bits(Self::Bits::one_shl(Self::FRAC_NBITS)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn minus_one() -> Option<Self> {
|
fn minus_one() -> Option<Self> {
|
||||||
if !Self::Bits::is_signed() || Self::int_bits() < 1 {
|
if !Self::Bits::IS_SIGNED || Self::INT_NBITS < 1 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(Self::from_bits(Self::Bits::all_ones_shl(Self::frac_bits())))
|
Some(Self::from_bits(Self::Bits::all_ones_shl(Self::FRAC_NBITS)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,13 +89,8 @@ macro_rules! sealed_fixed {
|
||||||
where
|
where
|
||||||
Frac: Unsigned + IsLessOrEqual<$Len, Output = True>,
|
Frac: Unsigned + IsLessOrEqual<$Len, Output = True>,
|
||||||
{
|
{
|
||||||
|
type FracNBits = Frac;
|
||||||
type Bits = $Bits;
|
type Bits = $Bits;
|
||||||
type Frac = Frac;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn frac_bits() -> u32 {
|
|
||||||
Frac::to_u32()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_fixed<F>(fixed: F) -> Self
|
fn from_fixed<F>(fixed: F) -> Self
|
||||||
|
@ -102,34 +102,22 @@ macro_rules! sealed_fixed {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn frac_mask() -> Self::Bits {
|
fn frac_mask() -> Self::Bits {
|
||||||
!Self::int_mask()
|
Self::FRAC_MASK as _
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn int_mask() -> Self::Bits {
|
fn int_mask() -> Self::Bits {
|
||||||
if Self::int_bits() == 0 {
|
Self::INT_MASK as _
|
||||||
0
|
|
||||||
} else {
|
|
||||||
!0 << Self::frac_bits()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn highest_frac_bit() -> Self::Bits {
|
fn highest_frac_bit() -> Self::Bits {
|
||||||
if Self::frac_bits() == 0 {
|
Self::FRAC_HI as _
|
||||||
0
|
|
||||||
} else {
|
|
||||||
1 << (Self::frac_bits() - 1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn lowest_int_bit() -> Self::Bits {
|
fn lowest_int_bit() -> Self::Bits {
|
||||||
if Self::int_bits() == 0 {
|
Self::INT_LO as _
|
||||||
0
|
|
||||||
} else {
|
|
||||||
1 << Self::frac_bits()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -150,8 +138,8 @@ macro_rules! sealed_fixed {
|
||||||
<Self::Bits as SealedInt>::Unsigned,
|
<Self::Bits as SealedInt>::Unsigned,
|
||||||
<Self::Bits as SealedInt>::Unsigned,
|
<Self::Bits as SealedInt>::Unsigned,
|
||||||
) {
|
) {
|
||||||
let frac_bits = <Self as SealedFixed>::frac_bits();
|
let frac_bits = <Self as SealedFixed>::FRAC_NBITS;
|
||||||
let int_bits = <Self as SealedFixed>::int_bits();
|
let int_bits = <Self as SealedFixed>::INT_NBITS;
|
||||||
|
|
||||||
let (neg, abs) = SealedInt::neg_abs(self.to_bits());
|
let (neg, abs) = SealedInt::neg_abs(self.to_bits());
|
||||||
let (int_abs, frac_abs) = if int_bits == 0 {
|
let (int_abs, frac_abs) = if int_bits == 0 {
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub trait SealedFloat: Copy + Debug + Display {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn exp_bias() -> i32 {
|
fn exp_bias() -> i32 {
|
||||||
let nbits = Self::Bits::nbits();
|
let nbits = Self::Bits::NBITS;
|
||||||
let exp_bits = nbits - Self::prec();
|
let exp_bits = nbits - Self::prec();
|
||||||
(1 << (exp_bits - 1)) - 1
|
(1 << (exp_bits - 1)) - 1
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ macro_rules! sealed_float {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn zero(neg: bool) -> $Float {
|
fn zero(neg: bool) -> $Float {
|
||||||
let nbits = <Self::Bits as SealedInt>::nbits();
|
let nbits = <Self::Bits as SealedInt>::NBITS;
|
||||||
let neg_mask = !0 << (nbits - 1);
|
let neg_mask = !0 << (nbits - 1);
|
||||||
let neg_bits = if neg { neg_mask } else { 0 };
|
let neg_bits = if neg { neg_mask } else { 0 };
|
||||||
<$Float>::from_bits(neg_bits)
|
<$Float>::from_bits(neg_bits)
|
||||||
|
@ -72,7 +72,7 @@ macro_rules! sealed_float {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn infinity(neg: bool) -> $Float {
|
fn infinity(neg: bool) -> $Float {
|
||||||
let nbits = <Self::Bits as SealedInt>::nbits();
|
let nbits = <Self::Bits as SealedInt>::NBITS;
|
||||||
let neg_mask = !0 << (nbits - 1);
|
let neg_mask = !0 << (nbits - 1);
|
||||||
let mant_mask = !(!0 << ($prec - 1));
|
let mant_mask = !(!0 << ($prec - 1));
|
||||||
let exp_mask = !(neg_mask | mant_mask);
|
let exp_mask = !(neg_mask | mant_mask);
|
||||||
|
@ -93,7 +93,7 @@ macro_rules! sealed_float {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn parts(self) -> (bool, i32, $Bits) {
|
fn parts(self) -> (bool, i32, $Bits) {
|
||||||
let nbits = <Self::Bits as SealedInt>::nbits();
|
let nbits = <Self::Bits as SealedInt>::NBITS;
|
||||||
let neg_mask = !0 << (nbits - 1);
|
let neg_mask = !0 << (nbits - 1);
|
||||||
let mant_mask = !(!0 << ($prec - 1));
|
let mant_mask = !(!0 << ($prec - 1));
|
||||||
let exp_mask = !(neg_mask | mant_mask);
|
let exp_mask = !(neg_mask | mant_mask);
|
||||||
|
@ -175,7 +175,7 @@ macro_rules! sealed_float {
|
||||||
frac_bits: u32,
|
frac_bits: u32,
|
||||||
int_bits: u32,
|
int_bits: u32,
|
||||||
) -> (bool, u128, bool) {
|
) -> (bool, u128, bool) {
|
||||||
let float_bits = Self::Bits::nbits() as i32;
|
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 fix_bits = (frac_bits + int_bits) as i32;
|
||||||
|
|
||||||
|
|
|
@ -14,13 +14,18 @@
|
||||||
// <https://opensource.org/licenses/MIT>.
|
// <https://opensource.org/licenses/MIT>.
|
||||||
|
|
||||||
use core::fmt::{Debug, Display};
|
use core::fmt::{Debug, Display};
|
||||||
|
use frac::{Bit, False, True, Unsigned, U1, U128, U16, U32, U64, U8};
|
||||||
use sealed_fixed::Widest;
|
use sealed_fixed::Widest;
|
||||||
|
|
||||||
pub trait SealedInt: Copy + Ord + Debug + Display {
|
pub trait SealedInt: Copy + Ord + Debug + Display {
|
||||||
|
type NBits: Unsigned;
|
||||||
|
type IsSigned: Bit;
|
||||||
type Unsigned: SealedInt;
|
type Unsigned: SealedInt;
|
||||||
|
|
||||||
fn is_signed() -> bool;
|
const NBITS: u32 = Self::NBits::U32;
|
||||||
fn nbits() -> u32;
|
const IS_SIGNED: bool = Self::IsSigned::BOOL;
|
||||||
|
const MSB: Self;
|
||||||
|
|
||||||
fn one_shl(shift: u32) -> Self;
|
fn one_shl(shift: u32) -> Self;
|
||||||
fn all_ones_shl(shift: u32) -> Self;
|
fn all_ones_shl(shift: u32) -> Self;
|
||||||
fn is_zero(self) -> bool;
|
fn is_zero(self) -> bool;
|
||||||
|
@ -34,27 +39,16 @@ pub trait SealedInt: Copy + Ord + Debug + Display {
|
||||||
|
|
||||||
fn neg_abs(self) -> (bool, Self::Unsigned);
|
fn neg_abs(self) -> (bool, Self::Unsigned);
|
||||||
fn from_neg_abs(neg: bool, abs: Self::Unsigned) -> Self;
|
fn from_neg_abs(neg: bool, abs: Self::Unsigned) -> Self;
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn msb() -> Self {
|
|
||||||
Self::one_shl(Self::nbits() - 1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! sealed_int {
|
macro_rules! sealed_int {
|
||||||
($Int:ident($Unsigned:ty, $is_signed:ident, $nbits:expr); $($rest:tt)*) => {
|
($Int:ident($NBits:ident, $IsSigned:ident, $Unsigned:ty); $($rest:tt)*) => {
|
||||||
impl SealedInt for $Int {
|
impl SealedInt for $Int {
|
||||||
|
type NBits = $NBits;
|
||||||
|
type IsSigned = $IsSigned;
|
||||||
type Unsigned = $Unsigned;
|
type Unsigned = $Unsigned;
|
||||||
|
|
||||||
#[inline]
|
const MSB: $Int = 1 << (Self::NBITS - 1);
|
||||||
fn is_signed() -> bool {
|
|
||||||
$is_signed
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn nbits() -> u32 {
|
|
||||||
$nbits
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn one_shl(shift: u32) -> $Int {
|
fn one_shl(shift: u32) -> $Int {
|
||||||
|
@ -74,9 +68,9 @@ macro_rules! sealed_int {
|
||||||
$($rest)*
|
$($rest)*
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($Int:ident($Unsigned:ty, false, $nbits:expr)) => {
|
($Unsigned:ident($NBits:ident)) => {
|
||||||
sealed_int! {
|
sealed_int! {
|
||||||
$Int($Unsigned, false, $nbits);
|
$Unsigned($NBits, False, $Unsigned);
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn neg_abs(self) -> (bool, Self::Unsigned) {
|
fn neg_abs(self) -> (bool, Self::Unsigned) {
|
||||||
|
@ -97,7 +91,7 @@ macro_rules! sealed_int {
|
||||||
dst_frac_bits: u32,
|
dst_frac_bits: u32,
|
||||||
dst_int_bits: u32,
|
dst_int_bits: u32,
|
||||||
) -> (Widest, bool) {
|
) -> (Widest, bool) {
|
||||||
let src_bits = <Self as SealedInt>::nbits() as i32;
|
let src_bits = <Self as SealedInt>::NBITS as i32;
|
||||||
let dst_bits = (dst_frac_bits + dst_int_bits) as i32;
|
let dst_bits = (dst_frac_bits + dst_int_bits) as i32;
|
||||||
|
|
||||||
if self == 0 {
|
if self == 0 {
|
||||||
|
@ -122,9 +116,9 @@ macro_rules! sealed_int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($Int:ident($Unsigned:ty, true, $nbits:expr)) => {
|
($Signed:ident($NBits:ident, $Unsigned:ty)) => {
|
||||||
sealed_int! {
|
sealed_int! {
|
||||||
$Int($Unsigned, true, $nbits);
|
$Signed($NBits, True, $Unsigned);
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn neg_abs(self) -> (bool, Self::Unsigned) {
|
fn neg_abs(self) -> (bool, Self::Unsigned) {
|
||||||
|
@ -137,7 +131,7 @@ macro_rules! sealed_int {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_neg_abs(neg: bool, abs: Self::Unsigned) -> Self {
|
fn from_neg_abs(neg: bool, abs: Self::Unsigned) -> Self {
|
||||||
debug_assert!(abs <= Self::Unsigned::msb());
|
debug_assert!(abs <= Self::Unsigned::MSB);
|
||||||
if neg {
|
if neg {
|
||||||
abs.wrapping_neg() as Self
|
abs.wrapping_neg() as Self
|
||||||
} else {
|
} else {
|
||||||
|
@ -152,7 +146,7 @@ macro_rules! sealed_int {
|
||||||
dst_frac_bits: u32,
|
dst_frac_bits: u32,
|
||||||
dst_int_bits: u32,
|
dst_int_bits: u32,
|
||||||
) -> (Widest, bool) {
|
) -> (Widest, bool) {
|
||||||
let src_bits = <Self as SealedInt>::nbits() as i32;
|
let src_bits = <Self as SealedInt>::NBITS as i32;
|
||||||
let dst_bits = (dst_frac_bits + dst_int_bits) as i32;
|
let dst_bits = (dst_frac_bits + dst_int_bits) as i32;
|
||||||
|
|
||||||
if self >= 0 {
|
if self >= 0 {
|
||||||
|
@ -185,17 +179,11 @@ macro_rules! sealed_int {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SealedInt for bool {
|
impl SealedInt for bool {
|
||||||
|
type NBits = U1;
|
||||||
|
type IsSigned = False;
|
||||||
type Unsigned = bool;
|
type Unsigned = bool;
|
||||||
|
|
||||||
#[inline]
|
const MSB: bool = true;
|
||||||
fn is_signed() -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn nbits() -> u32 {
|
|
||||||
1
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn one_shl(shift: u32) -> bool {
|
fn one_shl(shift: u32) -> bool {
|
||||||
|
@ -252,13 +240,13 @@ impl SealedInt for bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed_int! { i8(u8, true, 8) }
|
sealed_int! { i8(U8, u8) }
|
||||||
sealed_int! { i16(u16, true, 16) }
|
sealed_int! { i16(U16, u16) }
|
||||||
sealed_int! { i32(u32, true, 32) }
|
sealed_int! { i32(U32, u32) }
|
||||||
sealed_int! { i64(u64, true, 64) }
|
sealed_int! { i64(U64, u64) }
|
||||||
sealed_int! { i128(u128, true, 128) }
|
sealed_int! { i128(U128, u128) }
|
||||||
sealed_int! { u8(u8, false, 8) }
|
sealed_int! { u8(U8) }
|
||||||
sealed_int! { u16(u16, false, 16) }
|
sealed_int! { u16(U16) }
|
||||||
sealed_int! { u32(u32, false, 32) }
|
sealed_int! { u32(U32) }
|
||||||
sealed_int! { u64(u64, false, 64) }
|
sealed_int! { u64(U64) }
|
||||||
sealed_int! { u128(u128, false, 128) }
|
sealed_int! { u128(U128) }
|
||||||
|
|
Loading…
Reference in New Issue