#![cfg_attr(not(feature = "std"), no_std)]
#![warn(missing_docs)]
#![doc(html_root_url = "https://docs.rs/fixed/0.5.4")]
#![doc(test(attr(deny(warnings))))]
#![cfg_attr(feature = "fail-on-warnings", deny(warnings))]
#![allow(clippy::type_repetition_in_bounds)]
#[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;
mod int_helper;
#[cfg(feature = "serde")]
mod serdeize;
pub mod traits;
pub mod transcendental;
pub mod types;
mod wide_div;
mod wrapping;
use crate::{
arith::MulDivOverflow,
from_str::FromStrRadix,
traits::{FromFixed, ToFixed},
types::extra::{LeEqU128, LeEqU16, LeEqU32, LeEqU64, LeEqU8},
};
pub use crate::{from_str::ParseFixedError, wrapping::Wrapping};
use core::{
cmp::Ordering,
hash::{Hash, Hasher},
marker::PhantomData,
mem,
};
pub mod prelude {
pub use crate::traits::{FromFixed, ToFixed};
}
#[macro_use]
mod macros_from_to;
#[macro_use]
mod macros_round;
#[macro_use]
mod macros_no_frac;
#[macro_use]
mod macros_frac;
use codec::{Decode, Encode};
macro_rules! fixed {
(
$description:expr,
$Fixed:ident($Inner:ty, $LeEqU:tt, $s_nbits:expr, $s_nbits_m4:expr),
$nbytes:expr, $bytes_val:expr, $be_bytes:expr, $le_bytes:expr,
$UInner:ty, $Signedness:tt
) => {
fixed! {
$description,
$Fixed[stringify!($Fixed)]($Inner[stringify!($Inner)], $LeEqU, $s_nbits, $s_nbits_m4),
$nbytes, $bytes_val, $be_bytes, $le_bytes,
$UInner, $Signedness
}
};
(
$description:expr,
$Fixed:ident[$s_fixed:expr](
$Inner:ty[$s_inner:expr], $LeEqU:tt, $s_nbits:expr, $s_nbits_m4:expr
),
$nbytes:expr, $bytes_val:expr, $be_bytes:expr, $le_bytes:expr,
$UInner:ty, $Signedness:tt
) => {
comment! {
$description,
" number with `Frac` fractional bits.
Currently `Frac` is an [`Unsigned`] as provided by the
[typenum crate]; it is planned to move to [const generics] when they
are implemented by the Rust compiler.
# Examples
```rust
use substrate_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\");
```
[`Unsigned`]: https://docs.rs/typenum/^1.3/typenum/marker_traits/trait.Unsigned.html
[const generics]: https://github.com/rust-lang/rust/issues/44580
[typenum crate]: https://crates.io/crates/typenum
";
#[repr(transparent)]
#[derive(Encode, Decode)]
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! {
$description,
$Fixed[$s_fixed]($Inner[$s_inner], $s_nbits),
$nbytes, $bytes_val, $be_bytes, $le_bytes,
$UInner, $Signedness
}
fixed_frac! {
$description,
$Fixed[$s_fixed]($Inner[$s_inner], $LeEqU, $s_nbits, $s_nbits_m4),
$UInner, $Signedness
}
};
}
fixed! {
"An eight-bit fixed-point unsigned",
FixedU8(u8, LeEqU8, "8", "4"),
1, "0x12", "[0x12]", "[0x12]",
u8, Unsigned
}
fixed! {
"A 16-bit fixed-point unsigned",
FixedU16(u16, LeEqU16, "16", "12"),
2, "0x1234", "[0x12, 0x34]", "[0x34, 0x12]",
u16, Unsigned
}
fixed! {
"A 32-bit fixed-point unsigned",
FixedU32(u32, LeEqU32, "32", "28"),
4, "0x1234_5678", "[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]",
u32, Unsigned
}
fixed! {
"A 64-bit fixed-point unsigned",
FixedU64(u64, LeEqU64, "64", "60"),
8, "0x1234_5678_9ABC_DEF0",
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]",
"[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
u64, Unsigned
}
fixed! {
"A 128-bit fixed-point unsigned",
FixedU128(u128, LeEqU128, "128", "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]",
u128, Unsigned
}
fixed! {
"An eight-bit fixed-point signed",
FixedI8(i8, LeEqU8, "8", "4"),
1, "0x12", "[0x12]", "[0x12]",
u8, Signed
}
fixed! {
"A 16-bit fixed-point signed",
FixedI16(i16, LeEqU16, "16", "12"),
2, "0x1234", "[0x12, 0x34]", "[0x34, 0x12]",
u16, Signed
}
fixed! {
"A 32-bit fixed-point signed",
FixedI32(i32, LeEqU32, "32", "28"),
4, "0x1234_5678", "[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]",
u32, Signed
}
fixed! {
"A 64-bit fixed-point signed",
FixedI64(i64, LeEqU64, "64", "60"),
8, "0x1234_5678_9ABC_DEF0",
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]",
"[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
u64, Signed
}
fixed! {
"A 128-bit fixed-point signed",
FixedI128(i128, LeEqU128, "128", "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]",
u128, Signed
}
#[cfg(test)]
#[macro_use]
extern crate approx;
#[cfg(test)]
#[allow(clippy::cognitive_complexity)]
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)
);
}
}