#![cfg_attr(not(feature = "std"), no_std)]
#![warn(missing_docs)]
#![doc(html_root_url = "https://docs.rs/fixed/~1.6")]
#![doc(test(attr(deny(warnings))))]
#![cfg_attr(feature = "fail-on-warnings", deny(warnings))]
#[cfg(all(not(feature = "std"), test))]
extern crate std;
#[macro_use]
mod macros;
mod arith;
#[cfg(feature = "az")]
mod cast;
mod cmp;
pub mod consts;
mod convert;
mod display;
mod float_helper;
mod from_str;
mod helpers;
#[cfg(feature = "num-traits")]
mod impl_num_traits;
mod int_helper;
mod log10;
#[cfg(feature = "serde")]
mod serdeize;
pub mod traits;
pub mod types;
mod unwrapped;
mod wide_div;
mod wrapping;
#[cfg(feature = "num-traits")]
pub use crate::impl_num_traits::RadixParseFixedError;
use crate::{
arith::MulDivOverflow,
from_str::FromStrRadix,
log10::IntFracLog10,
traits::{FromFixed, ToFixed},
types::extra::{
IsLessOrEqual, LeEqU128, LeEqU16, LeEqU32, LeEqU64, LeEqU8, Sum, True, Unsigned, U12, U124,
U125, U126, U127, U128, U13, U14, U15, U16, U28, U29, U30, U31, U32, U4, U5, U6, U60, U61,
U62, U63, U64, U7, U8,
},
};
pub use crate::{from_str::ParseFixedError, unwrapped::Unwrapped, wrapping::Wrapping};
use core::{
cmp::Ordering,
hash::{Hash, Hasher},
marker::PhantomData,
mem,
ops::Add,
};
pub mod prelude {
pub use crate::traits::{
FromFixed, LosslessTryFrom, LosslessTryInto, LossyFrom, LossyInto, ToFixed,
};
}
#[macro_use]
mod macros_from_to;
#[macro_use]
mod macros_round;
#[macro_use]
mod macros_no_frac;
#[macro_use]
mod macros_frac;
#[macro_use]
mod macros_const;
macro_rules! fixed {
(
$description:expr,
$Fixed:ident(
$Inner:ty, $LeEqU:tt, $s_nbits:expr,
$s_nbits_m1:expr, $s_nbits_m2:expr, $s_nbits_m3:expr, $s_nbits_m4:expr
),
$nbytes:expr, $bytes_val:expr, $be_bytes:expr, $le_bytes:expr,
$UFixed:ident, $UInner:ty, $Signedness:tt,
$LeEqU_C0:tt, $LeEqU_C1:tt, $LeEqU_C2:tt, $LeEqU_C3:tt,
$Double:ident, $DoubleInner:ty, $HasDouble:tt
) => {
fixed! {
$description,
$Fixed[stringify!($Fixed)](
$Inner[stringify!($Inner)], $LeEqU, $s_nbits,
$s_nbits_m1, $s_nbits_m2, $s_nbits_m3, $s_nbits_m4
),
$nbytes, $bytes_val, $be_bytes, $le_bytes,
$UFixed[stringify!($UFixed)], $UInner, $Signedness,
$LeEqU_C0, $LeEqU_C1, $LeEqU_C2, $LeEqU_C3,
$Double, $DoubleInner, $HasDouble
}
};
(
$description:expr,
$Fixed:ident[$s_fixed:expr](
$Inner:ty[$s_inner:expr], $LeEqU:tt, $s_nbits:expr,
$s_nbits_m1:expr, $s_nbits_m2:expr, $s_nbits_m3:expr, $s_nbits_m4:expr
),
$nbytes:expr, $bytes_val:expr, $be_bytes:expr, $le_bytes:expr,
$UFixed:ident[$s_ufixed:expr], $UInner:ty, $Signedness:tt,
$LeEqU_C0:tt, $LeEqU_C1:tt, $LeEqU_C2:tt, $LeEqU_C3:tt,
$Double:ident, $DoubleInner:ty, $HasDouble:tt
) => {
comment! {
$description,
" number with `Frac` fractional bits.
`Frac` is an [`Unsigned`] as provided by the [*typenum* crate]; the
plan is to move to [const generics] in version 2 when they are
supported by the Rust compiler.
# Examples
```rust
use fixed::{types::extra::U3, ", $s_fixed, "};
let eleven = ", $s_fixed, "::<U3>::from_num(11);
assert_eq!(eleven, ", $s_fixed, "::<U3>::from_bits(11 << 3));
assert_eq!(eleven, 11);
assert_eq!(eleven.to_string(), \"11\");
let two_point_75 = eleven / 4;
assert_eq!(two_point_75, ", $s_fixed, "::<U3>::from_bits(11 << 1));
assert_eq!(two_point_75, 2.75);
assert_eq!(two_point_75.to_string(), \"2.8\");
```
[*typenum* crate]: https://crates.io/crates/typenum
[`Unsigned`]: https://docs.rs/typenum/^1.10/typenum/marker_traits/trait.Unsigned.html
[const generics]: https://github.com/rust-lang/rust/issues/44580
";
#[repr(transparent)]
pub struct $Fixed<Frac> {
bits: $Inner,
phantom: PhantomData<Frac>,
}
}
impl<Frac> Clone for $Fixed<Frac> {
#[inline]
fn clone(&self) -> $Fixed<Frac> {
$Fixed {
bits: self.bits,
phantom: PhantomData,
}
}
}
impl<Frac> Copy for $Fixed<Frac> {}
impl<Frac> Default for $Fixed<Frac> {
#[inline]
fn default() -> Self {
$Fixed {
bits: Default::default(),
phantom: PhantomData,
}
}
}
impl<Frac> Hash for $Fixed<Frac> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.bits.hash(state);
}
}
fixed_no_frac! {
$Fixed[$s_fixed]($Inner[$s_inner], $LeEqU, $s_nbits),
$nbytes, $bytes_val, $be_bytes, $le_bytes,
$UFixed[$s_ufixed], $UInner, $Signedness,
$Double, $DoubleInner, $HasDouble
}
fixed_frac! {
$Fixed[$s_fixed]($Inner[$s_inner], $LeEqU, $s_nbits, $s_nbits_m1, $s_nbits_m4),
$UFixed, $UInner, $Signedness
}
fixed_const! {
$Fixed[$s_fixed]($LeEqU, $s_nbits, $s_nbits_m1, $s_nbits_m2, $s_nbits_m3, $s_nbits_m4),
$LeEqU_C0, $LeEqU_C1, $LeEqU_C2, $LeEqU_C3,
$Signedness
}
};
}
fixed! {
"An eight-bit fixed-point unsigned",
FixedU8(u8, LeEqU8, "8", "7", "6", "5", "4"),
1, "0x12", "[0x12]", "[0x12]",
FixedU8, u8, Unsigned,
U8, U7, U6, U5,
FixedU16, u16, True
}
fixed! {
"A 16-bit fixed-point unsigned",
FixedU16(u16, LeEqU16, "16", "15", "14", "13", "12"),
2, "0x1234", "[0x12, 0x34]", "[0x34, 0x12]",
FixedU16, u16, Unsigned,
U16, U15, U14, U13,
FixedU32, u32, True
}
fixed! {
"A 32-bit fixed-point unsigned",
FixedU32(u32, LeEqU32, "32", "31", "30", "29", "28"),
4, "0x1234_5678", "[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]",
FixedU32, u32, Unsigned,
U32, U31, U30, U29,
FixedU64, u64, True
}
fixed! {
"A 64-bit fixed-point unsigned",
FixedU64(u64, LeEqU64, "64", "63", "62", "61", "60"),
8, "0x1234_5678_9ABC_DEF0",
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]",
"[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
FixedU64, u64, Unsigned,
U64, U63, U62, U61,
FixedU128, u128, True
}
fixed! {
"A 128-bit fixed-point unsigned",
FixedU128(u128, LeEqU128, "128", "127", "126", "125", "124"),
16, "0x1234_5678_9ABC_DEF0_1234_5678_9ABC_DEF0",
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, \
0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]",
"[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, \
0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
FixedU128, u128, Unsigned,
U128, U127, U126, U125,
FixedU128, u128, False
}
fixed! {
"An eight-bit fixed-point signed",
FixedI8(i8, LeEqU8, "8", "7", "6", "5", "4"),
1, "0x12", "[0x12]", "[0x12]",
FixedU8, u8, Signed,
U7, U6, U5, U4,
FixedI16, i16, True
}
fixed! {
"A 16-bit fixed-point signed",
FixedI16(i16, LeEqU16, "16", "15", "14", "13", "12"),
2, "0x1234", "[0x12, 0x34]", "[0x34, 0x12]",
FixedU16, u16, Signed,
U15, U14, U13, U12,
FixedI32, i32, True
}
fixed! {
"A 32-bit fixed-point signed",
FixedI32(i32, LeEqU32, "32", "31", "30", "29", "28"),
4, "0x1234_5678", "[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]",
FixedU32, u32, Signed,
U31, U30, U29, U28,
FixedI64, i64, True
}
fixed! {
"A 64-bit fixed-point signed",
FixedI64(i64, LeEqU64, "64", "63", "62", "61", "60"),
8, "0x1234_5678_9ABC_DEF0",
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]",
"[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
FixedU64, u64, Signed,
U63, U62, U61, U60,
FixedI128, i128, True
}
fixed! {
"A 128-bit fixed-point signed",
FixedI128(i128, LeEqU128, "128", "127", "126", "125", "124"),
16, "0x1234_5678_9ABC_DEF0_1234_5678_9ABC_DEF0",
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, \
0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]",
"[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, \
0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
FixedU128, u128, Signed,
U127, U126, U125, U124,
FixedI128, i128, False
}
#[macro_export]
macro_rules! const_fixed_from_int {
($(const $NAME:ident: $Fixed:ty = $int:expr;)*) => { $(
const $NAME: $Fixed = {
const FRAC: u32 = <$Fixed>::FRAC_NBITS;
const INT: $Fixed = <$Fixed>::from_bits($int);
const LSB: $Fixed = <$Fixed>::from_bits(1);
const ONE_A: $Fixed = <$Fixed>::from_bits(LSB.to_bits() << FRAC / 2);
const ONE_B: $Fixed = <$Fixed>::from_bits(LSB.to_bits() << FRAC - FRAC / 2);
<$Fixed>::from_bits(INT.to_bits() * ONE_A.to_bits() * ONE_B.to_bits())
};
)* };
}
fn _compile_fail_tests() {}
#[cfg(test)]
mod tests {
use crate::types::{I0F32, I16F16, I1F31, U0F32, U16F16};
#[test]
fn rounding_signed() {
let f = I0F32::from_bits(-1 << 31);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I0F32::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I0F32::from_num(0), true));
assert_eq!(f.overflowing_round(), (I0F32::from_num(0), true));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I0F32::from_num(0), false)
);
let f = I0F32::from_bits((-1 << 31) + 1);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I0F32::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I0F32::from_num(0), true));
assert_eq!(f.overflowing_round(), (I0F32::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I0F32::from_num(0), false)
);
let f = I0F32::from_bits(0);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I0F32::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I0F32::from_num(0), false));
assert_eq!(f.overflowing_round(), (I0F32::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I0F32::from_num(0), false)
);
let f = I0F32::from_bits((1 << 30) - 1 + (1 << 30));
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I0F32::from_num(0), true));
assert_eq!(f.overflowing_floor(), (I0F32::from_num(0), false));
assert_eq!(f.overflowing_round(), (I0F32::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I0F32::from_num(0), false)
);
let f = I1F31::from_bits((-1) << 31);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), -1);
assert_eq!(f.overflowing_ceil(), (I1F31::from_num(-1), false));
assert_eq!(f.overflowing_floor(), (I1F31::from_num(-1), false));
assert_eq!(f.overflowing_round(), (I1F31::from_num(-1), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I1F31::from_num(-1), false)
);
let f = I1F31::from_bits(((-1) << 30) - 1);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I1F31::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I1F31::from_num(-1), false));
assert_eq!(f.overflowing_round(), (I1F31::from_num(-1), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I1F31::from_num(-1), false)
);
let f = I1F31::from_bits((-1) << 30);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I1F31::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I1F31::from_num(-1), false));
assert_eq!(f.overflowing_round(), (I1F31::from_num(-1), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I1F31::from_num(0), false)
);
let f = I1F31::from_bits(((-1) << 30) + 1);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I1F31::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I1F31::from_num(-1), false));
assert_eq!(f.overflowing_round(), (I1F31::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I1F31::from_num(0), false)
);
let f = I1F31::from_bits((1 << 30) - 1);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I1F31::from_num(-1), true));
assert_eq!(f.overflowing_floor(), (I1F31::from_num(0), false));
assert_eq!(f.overflowing_round(), (I1F31::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I1F31::from_num(0), false)
);
let f = I1F31::from_bits(1 << 30);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I1F31::from_num(-1), true));
assert_eq!(f.overflowing_floor(), (I1F31::from_num(0), false));
assert_eq!(f.overflowing_round(), (I1F31::from_num(-1), true));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I1F31::from_num(0), false)
);
let f = I1F31::from_bits(0);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I1F31::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I1F31::from_num(0), false));
assert_eq!(f.overflowing_round(), (I1F31::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I1F31::from_num(0), false)
);
let f = I1F31::from_bits((1 << 30) + 1);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I1F31::from_num(-1), true));
assert_eq!(f.overflowing_floor(), (I1F31::from_num(0), false));
assert_eq!(f.overflowing_round(), (I1F31::from_num(-1), true));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I1F31::from_num(-1), true)
);
let f = I16F16::from_bits(((-7) << 15) - 1);
assert_eq!(f.to_num::<i32>(), -4);
assert_eq!(f.round_to_zero(), -3);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(-3), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(-4), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(-4), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(-4), false)
);
let f = I16F16::from_bits((-7) << 15);
assert_eq!(f.to_num::<i32>(), -4);
assert_eq!(f.round_to_zero(), -3);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(-3), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(-4), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(-4), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(-4), false)
);
let f = I16F16::from_bits(((-7) << 15) + 1);
assert_eq!(f.to_num::<i32>(), -4);
assert_eq!(f.round_to_zero(), -3);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(-3), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(-4), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(-3), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(-3), false)
);
let f = I16F16::from_bits(((-5) << 15) - 1);
assert_eq!(f.to_num::<i32>(), -3);
assert_eq!(f.round_to_zero(), -2);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(-2), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(-3), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(-3), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(-3), false)
);
let f = I16F16::from_bits((-5) << 15);
assert_eq!(f.to_num::<i32>(), -3);
assert_eq!(f.round_to_zero(), -2);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(-2), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(-3), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(-3), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(-2), false)
);
let f = I16F16::from_bits(((-5) << 15) + 1);
assert_eq!(f.to_num::<i32>(), -3);
assert_eq!(f.round_to_zero(), -2);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(-2), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(-3), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(-2), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(-2), false)
);
let f = I16F16::from_bits((-1) << 16);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), -1);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(-1), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(-1), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(-1), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(-1), false)
);
let f = I16F16::from_bits(((-1) << 15) - 1);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(-1), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(-1), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(-1), false)
);
let f = I16F16::from_bits((-1) << 15);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(-1), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(-1), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(0), false)
);
let f = I16F16::from_bits(((-1) << 15) + 1);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(-1), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(0), false)
);
let f = I16F16::from_bits(0);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(0), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(0), false)
);
let f = I16F16::from_bits((1 << 15) - 1);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(1), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(0), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(0), false)
);
let f = I16F16::from_bits(1 << 15);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(1), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(0), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(1), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(0), false)
);
let f = I16F16::from_bits((1 << 15) + 1);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(1), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(0), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(1), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(1), false)
);
let f = I16F16::from_bits(1 << 16);
assert_eq!(f.to_num::<i32>(), 1);
assert_eq!(f.round_to_zero(), 1);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(1), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(1), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(1), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(1), false)
);
let f = I16F16::from_bits((5 << 15) - 1);
assert_eq!(f.to_num::<i32>(), 2);
assert_eq!(f.round_to_zero(), 2);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(3), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(2), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(2), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(2), false)
);
let f = I16F16::from_bits(5 << 15);
assert_eq!(f.to_num::<i32>(), 2);
assert_eq!(f.round_to_zero(), 2);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(3), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(2), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(3), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(2), false)
);
let f = I16F16::from_bits((5 << 15) + 1);
assert_eq!(f.to_num::<i32>(), 2);
assert_eq!(f.round_to_zero(), 2);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(3), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(2), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(3), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(3), false)
);
let f = I16F16::from_bits((7 << 15) - 1);
assert_eq!(f.to_num::<i32>(), 3);
assert_eq!(f.round_to_zero(), 3);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(4), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(3), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(3), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(3), false)
);
let f = I16F16::from_bits(7 << 15);
assert_eq!(f.to_num::<i32>(), 3);
assert_eq!(f.round_to_zero(), 3);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(4), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(3), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(4), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(4), false)
);
let f = I16F16::from_bits((7 << 15) + 1);
assert_eq!(f.to_num::<i32>(), 3);
assert_eq!(f.round_to_zero(), 3);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(4), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(3), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(4), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(4), false)
);
}
#[test]
fn rounding_unsigned() {
let f = U0F32::from_bits(0);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (U0F32::from_num(0), false));
assert_eq!(f.overflowing_floor(), (U0F32::from_num(0), false));
assert_eq!(f.overflowing_round(), (U0F32::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U0F32::from_num(0), false)
);
let f = U0F32::from_bits((1 << 31) - 1);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (U0F32::from_num(0), true));
assert_eq!(f.overflowing_floor(), (U0F32::from_num(0), false));
assert_eq!(f.overflowing_round(), (U0F32::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U0F32::from_num(0), false)
);
let f = U0F32::from_bits(1 << 31);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (U0F32::from_num(0), true));
assert_eq!(f.overflowing_floor(), (U0F32::from_num(0), false));
assert_eq!(f.overflowing_round(), (U0F32::from_num(0), true));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U0F32::from_num(0), false)
);
let f = U0F32::from_bits((1 << 31) + 1);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (U0F32::from_num(0), true));
assert_eq!(f.overflowing_floor(), (U0F32::from_num(0), false));
assert_eq!(f.overflowing_round(), (U0F32::from_num(0), true));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U0F32::from_num(0), true)
);
let f = U16F16::from_bits(0);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (U16F16::from_num(0), false));
assert_eq!(f.overflowing_floor(), (U16F16::from_num(0), false));
assert_eq!(f.overflowing_round(), (U16F16::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(0), false)
);
let f = U16F16::from_bits((1 << 15) - 1);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (U16F16::from_num(1), false));
assert_eq!(f.overflowing_floor(), (U16F16::from_num(0), false));
assert_eq!(f.overflowing_round(), (U16F16::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(0), false)
);
let f = U16F16::from_bits(1 << 15);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (U16F16::from_num(1), false));
assert_eq!(f.overflowing_floor(), (U16F16::from_num(0), false));
assert_eq!(f.overflowing_round(), (U16F16::from_num(1), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(0), false)
);
let f = U16F16::from_bits((1 << 15) + 1);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (U16F16::from_num(1), false));
assert_eq!(f.overflowing_floor(), (U16F16::from_num(0), false));
assert_eq!(f.overflowing_round(), (U16F16::from_num(1), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(1), false)
);
let f = U16F16::from_bits(1 << 16);
assert_eq!(f.to_num::<i32>(), 1);
assert_eq!(f.round_to_zero(), 1);
assert_eq!(f.overflowing_ceil(), (U16F16::from_num(1), false));
assert_eq!(f.overflowing_floor(), (U16F16::from_num(1), false));
assert_eq!(f.overflowing_round(), (U16F16::from_num(1), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(1), false)
);
let f = U16F16::from_bits((5 << 15) - 1);
assert_eq!(f.to_num::<i32>(), 2);
assert_eq!(f.round_to_zero(), 2);
assert_eq!(f.overflowing_ceil(), (U16F16::from_num(3), false));
assert_eq!(f.overflowing_floor(), (U16F16::from_num(2), false));
assert_eq!(f.overflowing_round(), (U16F16::from_num(2), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(2), false)
);
let f = U16F16::from_bits(5 << 15);
assert_eq!(f.to_num::<i32>(), 2);
assert_eq!(f.round_to_zero(), 2);
assert_eq!(f.overflowing_ceil(), (U16F16::from_num(3), false));
assert_eq!(f.overflowing_floor(), (U16F16::from_num(2), false));
assert_eq!(f.overflowing_round(), (U16F16::from_num(3), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(2), false)
);
let f = U16F16::from_bits((5 << 15) + 1);
assert_eq!(f.to_num::<i32>(), 2);
assert_eq!(f.round_to_zero(), 2);
assert_eq!(f.overflowing_ceil(), (U16F16::from_num(3), false));
assert_eq!(f.overflowing_floor(), (U16F16::from_num(2), false));
assert_eq!(f.overflowing_round(), (U16F16::from_num(3), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(3), false)
);
let f = U16F16::from_bits((7 << 15) - 1);
assert_eq!(f.to_num::<i32>(), 3);
assert_eq!(f.round_to_zero(), 3);
assert_eq!(f.overflowing_ceil(), (U16F16::from_num(4), false));
assert_eq!(f.overflowing_floor(), (U16F16::from_num(3), false));
assert_eq!(f.overflowing_round(), (U16F16::from_num(3), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(3), false)
);
let f = U16F16::from_bits(7 << 15);
assert_eq!(f.to_num::<i32>(), 3);
assert_eq!(f.round_to_zero(), 3);
assert_eq!(f.overflowing_ceil(), (U16F16::from_num(4), false));
assert_eq!(f.overflowing_floor(), (U16F16::from_num(3), false));
assert_eq!(f.overflowing_round(), (U16F16::from_num(4), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(4), false)
);
let f = U16F16::from_bits((7 << 15) + 1);
assert_eq!(f.to_num::<i32>(), 3);
assert_eq!(f.round_to_zero(), 3);
assert_eq!(f.overflowing_ceil(), (U16F16::from_num(4), false));
assert_eq!(f.overflowing_floor(), (U16F16::from_num(3), false));
assert_eq!(f.overflowing_round(), (U16F16::from_num(4), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(4), false)
);
}
#[test]
fn reciprocals() {
assert_eq!(
U0F32::from_num(0.75).overflowing_recip(),
(U0F32::from_bits(0x5555_5555), true)
);
assert_eq!(
U0F32::from_num(0.375).overflowing_recip(),
(U0F32::from_bits(0xAAAA_AAAA), true)
);
assert_eq!(
I0F32::from_num(0.375).overflowing_recip(),
(I0F32::from_bits(-0x5555_5556), true)
);
assert_eq!(
I0F32::from_num(-0.375).overflowing_recip(),
(I0F32::from_bits(0x5555_5556), true)
);
assert_eq!(
I0F32::from_num(-0.5).overflowing_recip(),
(I0F32::from_num(0), true)
);
assert_eq!(
I1F31::from_num(0.375).overflowing_recip(),
(I1F31::from_bits(0x5555_5555), true)
);
assert_eq!(
I1F31::from_num(-0.375).overflowing_recip(),
(I1F31::from_bits(-0x5555_5555), true)
);
assert_eq!(
I1F31::from_num(0.75).overflowing_recip(),
(I1F31::from_bits(-0x5555_5556), true)
);
assert_eq!(
I1F31::from_num(-0.75).overflowing_recip(),
(I1F31::from_bits(0x5555_5556), true)
);
assert_eq!(
I1F31::from_num(-0.5).overflowing_recip(),
(I1F31::from_num(0), true)
);
assert_eq!(
I1F31::from_num(-1).overflowing_recip(),
(I1F31::from_num(-1), false)
);
}
}