#![cfg_attr(not(feature = "std"), no_std)]
#![warn(missing_docs)]
#![warn(unsafe_op_in_unsafe_fn)]
#![doc(html_root_url = "https://docs.rs/fixed/~1.28")]
#![doc(html_logo_url = "data:image/svg+xml;base64,
PHN2ZyB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCIgdmVyc2lvbj0iMS4xIiB2aWV3Qm94PSIwIDAgMzMuODY3IDMzLjg2NyIgeG1s
bnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcz48Y2xpcFBhdGggaWQ9ImIiPjxjaXJjbGUgY3g9IjE2LjkzMyIg
Y3k9IjI4MC4wNyIgcj0iMTYuOTMzIiBmaWxsPSIjMDA3MmIyIi8+PC9jbGlwUGF0aD48Y2xpcFBhdGggaWQ9ImEiPjxjaXJjbGUg
Y3g9IjE2LjkzMyIgY3k9IjI4MC4wNyIgcj0iMTYuOTMzIiBmaWxsPSIjMDA3MmIyIi8+PC9jbGlwUGF0aD48L2RlZnM+PGcgdHJh
bnNmb3JtPSJ0cmFuc2xhdGUoMCAtMjYzLjEzKSI+PGNpcmNsZSBjeD0iMTYuOTMzIiBjeT0iMjgwLjA3IiByPSIxNi45MzMiIGZp
bGw9IiNmN2YxYTEiLz48ZyBmaWxsPSIjMDA3MmIyIj48cGF0aCBkPSJtMTUuMzQ2IDI4My41MWgzLjE3NXMwIDAuNzkzNzYgMC41
MjkxNyAxLjg1MjFoLTQuMjMzM2MwLjUyOTE2LTEuMDU4MyAwLjUyOTE2LTEuODUyMSAwLjUyOTE2LTEuODUyMXoiIHN0cm9rZS13
aWR0aD0iLjUyOTE3Ii8+PHBhdGggZD0ibTM0LjExMiAyODUuNTRjMi4yODYgMCAzLjgxLTEuMjg2OSAzLjgxLTIuOTgwMyAwLTEu
NDIyNC0wLjgyOTczLTIuMjUyMS0xLjg2MjctMi44MTA5di0wLjA2NzdjMC43NDUwNy0wLjQ5MTA3IDEuNDA1NS0xLjMyMDggMS40
MDU1LTIuMzUzNyAwLTEuNzc4LTEuMzAzOS0yLjk0NjQtMy4yNjgxLTIuOTQ2NC0xLjk5ODEgMC0zLjQzNzUgMS4xMzQ1LTMuNDM3
NSAyLjk2MzMgMCAxLjEzNDUgMC42MDk2IDEuOTEzNSAxLjQzOTMgMi41NHYwLjA2NzdjLTEuMDE2IDAuNTQxODctMS44Mjg4IDEu
MzM3Ny0xLjgyODggMi42NDE2IDAgMS43NDQxIDEuNTkxNyAyLjk0NjQgMy43NDIzIDIuOTQ2NHptMC42NzczMy02LjQ2ODVjLTEu
MTAwNy0wLjQyMzMzLTEuODQ1Ny0wLjg0NjY3LTEuODQ1Ny0xLjcyNzIgMC0wLjgyOTczIDAuNTQxODctMS4yMzYxIDEuMjAyMy0x
LjIzNjEgMC44MTI4IDAgMS4zMDM5IDAuNTU4OCAxLjMwMzkgMS4zODg1IDAgMC41NTg4LTAuMjM3MDcgMS4wODM3LTAuNjYwNCAx
LjU3NDh6bS0wLjYyNjUzIDQuNzQxM2MtMC44OTc0NiAwLTEuNjU5NS0wLjU1ODgtMS42NTk1LTEuNTA3MSAwLTAuNjYwNCAwLjM1
NTYtMS4yNyAwLjgyOTczLTEuNzEwMyAxLjM1NDcgMC41NzU3MyAyLjI2OTEgMC45MzEzMyAyLjI2OTEgMS44Nzk2IDAgMC44OTc0
Ny0wLjYwOTYgMS4zMzc3LTEuNDM5MyAxLjMzNzd6IiBjbGlwLXBhdGg9InVybCgjYikiLz48cGF0aCBkPSJtMjEuMzQ0IDI4NS4z
NGg3LjU2OTJ2LTIuMDk5N2gtMi40MDQ1Yy0wLjQ5MTA3IDAtMS4yMzYxIDAuMDY3Ny0xLjc5NDkgMC4xMzU0NyAxLjkxMzUtMS44
Nzk2IDMuNjc0NS0zLjY0MDcgMy42NzQ1LTUuNTg4IDAtMi4wNDg5LTEuNDM5My0zLjQwMzYtMy41NTYtMy40MDM2LTEuNTA3MSAw
LTIuNTIzMSAwLjU5MjY3LTMuNTU2IDEuNzYxMWwxLjMwMzkgMS4yODY5YzAuNTQxODctMC41NzU3MyAxLjEzNDUtMS4xMDA3IDEu
OTEzNS0xLjEwMDcgMC45MzEzMyAwIDEuNTI0IDAuNTc1NzQgMS41MjQgMS42MjU2IDAgMS41MDcxLTEuOTY0MyAzLjQzNzUtNC42
NzM2IDUuODQyeiIvPjxwYXRoIGQ9Im0xNi45MzMgMjg0LjE2YzEuNzI3MiAwIDMuMDE0MS0xLjM1NDcgMy4wMTQxLTMuMTE1NyAw
LTEuNzk0OS0xLjI4NjktMy4xNDk2LTMuMDE0MS0zLjE0OTYtMS43MjcyIDAtMy4wMTQxIDEuMzU0Ny0zLjAxNDEgMy4xNDk2IDAg
MS43NjExIDEuMjg2OSAzLjExNTcgMy4wMTQxIDMuMTE1N3oiLz48cGF0aCBkPSJtOC45MTU0IDI4MC4zOGMwLjgxMjggMCAxLjQw
NTUgMC40MjMzNCAxLjQwNTUgMS41NTc5IDAgMS4yMTkyLTAuNjA5NiAxLjc0NDEtMS4zNTQ3IDEuNzQ0MXMtMS40NTYzLTAuNTQx
ODYtMS42NzY0LTIuMjM1MmMwLjQ0MDI3LTAuNzYyIDEuMDY2OC0xLjA2NjggMS42MjU2LTEuMDY2OHptMC4xMDE2IDUuMTY0N2Mx
Ljk0NzMgMCAzLjU3MjktMS4zNzE2IDMuNTcyOS0zLjYwNjggMC0yLjI2OTEtMS4zNTQ3LTMuMzE4OS0zLjIwMDQtMy4zMTg5LTAu
NjYwNCAwLTEuNTkxNyAwLjQyMzMzLTIuMTUwNSAxLjEzNDUgMC4wODQ2NjctMi41MDYxIDEuMDMyOS0zLjM1MjggMi4yMTgzLTMu
MzUyOCAwLjYyNjUzIDAgMS4zMDM5IDAuMzU1NiAxLjY3NjQgMC43NjJsMS4zMDM5LTEuNDkwMWMtMC42NzczMy0wLjY5NDI3LTEu
NzEwMy0xLjI4NjktMy4xMzI3LTEuMjg2OS0yLjI2OTEgMC00LjM1MTkgMS44MTE5LTQuMzUxOSA1LjgyNTEgMCAzLjc3NjEgMS45
ODEyIDUuMzM0IDQuMDY0IDUuMzM0eiIvPjxwYXRoIGQ9Im0tMC4yMTE2NyAyODUuNTRjMi4zMDI5IDAgMy44NDM5LTEuOTY0MyAz
Ljg0MzktNS42MjE5cy0xLjU0MDktNS41MzcyLTMuODQzOS01LjUzNzJjLTIuMzAyOSAwLTMuODQzOSAxLjg3OTYtMy44NDM5IDUu
NTM3MnMxLjU0MDkgNS42MjE5IDMuODQzOSA1LjYyMTl6bTAtMS45MzA0Yy0wLjgyOTczIDAtMS40OTAxLTAuNzYyLTEuNDkwMS0z
LjY5MTUgMC0yLjk0NjQgMC42NjA0LTMuNjA2OCAxLjQ5MDEtMy42MDY4IDAuODQ2NjcgMCAxLjQ5MDEgMC42NjA0IDEuNDkwMSAz
LjYwNjggMCAyLjkyOTUtMC42NDM0NyAzLjY5MTUtMS40OTAxIDMuNjkxNXoiIGNsaXAtcGF0aD0idXJsKCNhKSIvPjwvZz48L2c+
PC9zdmc+Cg==
")]
#![doc(test(attr(deny(warnings))))]
#![cfg_attr(feature = "fail-on-warnings", deny(warnings))]
#![cfg_attr(feature = "nightly-float", feature(f16, f128))]
#[cfg(all(not(feature = "std"), test))]
extern crate std;
#[macro_use]
mod macros;
mod arith;
#[cfg(feature = "borsh")]
mod borshize;
mod bytes;
mod cast;
mod cmp;
mod cmp_fixed;
pub mod consts;
mod convert;
mod debug_hex;
mod display;
pub mod f128;
mod float_helper;
mod from_str;
mod helpers;
mod hypot;
#[cfg(feature = "arbitrary")]
mod impl_arbitrary;
mod impl_bytemuck;
#[cfg(feature = "num-traits")]
mod impl_num_traits;
mod int256;
mod int_helper;
mod inv_lerp;
mod lerp;
mod log;
mod log10;
mod prim_traits;
mod saturating;
#[cfg(feature = "serde")]
mod serdeize;
mod sqrt;
pub mod traits;
mod traits_bits;
pub mod types;
mod unwrapped;
mod wrapping;
#[cfg(feature = "num-traits")]
pub use crate::impl_num_traits::RadixParseFixedError;
pub use crate::{
f128::private::F128, from_str::ParseFixedError, saturating::Saturating, unwrapped::Unwrapped,
wrapping::Wrapping,
};
use crate::{
log::Base,
traits::{FromFixed, ToFixed},
types::extra::{
Diff, IsLessOrEqual, LeEqU128, LeEqU16, LeEqU32, LeEqU64, LeEqU8, Sum, True, Unsigned, U0,
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,
},
};
use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8};
use core::{
hash::{Hash, Hasher},
marker::PhantomData,
ops::{Add, Sub},
};
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 = $description:literal,
{Self, Inner} = {$Self:ident, $Inner:ident},
Signedness = $Signedness:ident,
LeEqU = $LeEqU:ident,
{Unm1, Un} = {$Unm1:ident, $Un:ident},
[nm4 ..= np1]
= [$nm4:literal, $nm3:literal, $nm2:literal, $nm1:literal, $n:literal, $np1:literal],
{ISelf, IInner} = {$ISelf:ident, $IInner:ident},
{USelf, UInner} = {$USelf:ident, $UInner:ident},
NonZeroUInner = $NonZeroUInner:ident,
[LeEqUC0 ..= LeEqUC3] = [$LeEqUC0:ident, $LeEqUC1:ident, $LeEqUC2:ident, $LeEqUC3:ident],
nbytes = $nbytes:literal,
{bytes_val, rev_bytes_val} = {$bytes_val:literal, $rev_bytes_val:literal $(,)?},
{be_bytes, le_bytes} = {$be_bytes:literal, $le_bytes:literal $(,)?},
$(
n2 = $n2:literal,
{Double, DoubleInner} = {$Double:ident, $DoubleInner:ident},
{IDouble, IDoubleInner} = {$IDouble:ident, $IDoubleInner:ident},
)?
) => {
comment! {
$description, "-bit ",
if_signed_unsigned!($Signedness, "signed", "unsigned"),
" number with `Frac` fractional bits.
The number has ", $n, " bits, of which <i>f</i> = `Frac` are
fractional bits and ", $n, " − <i>f</i> are integer bits.
The value <i>x</i> can lie in the range ",
if_signed_unsigned!(
$Signedness,
concat!("−2<sup>", $nm1, "</sup>/2<sup><i>f</i></sup>"),
"0",
),
" ≤ <i>x</i> < 2<sup>",
if_signed_unsigned!($Signedness, $nm1, $n),
"</sup>/2<sup><i>f</i></sup>. The difference between successive
numbers is constant throughout the range: <i>Δ</i> = 1/2<sup><i>f</i></sup>.
For <code>", stringify!($Self), "\\<[U0]></code>, <i>f</i> = 0 and
<i>Δ</i> = 1, and the fixed-point number behaves like ",
if_signed_unsigned!($Signedness, "an", "a"),
" [`", stringify!($Inner), "`] with the value lying in the range ",
if_signed_unsigned!(
$Signedness,
concat!("−2<sup>", $nm1, "</sup>"),
"0",
),
" ≤ <i>x</i> < 2<sup>",
if_signed_unsigned!($Signedness, $nm1, $n),
"</sup>. For <code>", stringify!($Self), "\\<[U", $n, "]></code>,
<i>f</i> = ", $n, " and
<i>Δ</i> = 1/2<sup>", $n, "</sup>, and the value lies in the
range ",
if_signed_unsigned!(
$Signedness,
"−1/2 ≤ <i>x</i> < 1/2",
"0 ≤ <i>x</i> < 1",
),
".
`Frac` is an [`Unsigned`] as provided by the [*typenum* crate]; the plan is to
to have a major version 2 where `Frac` is replaced by `FRAC` of type [`i32`]
when the Rust compiler’s [`generic_const_exprs` feature] is ready and stabilized.
An [alpha version] is already available.
`", stringify!($Self), "<Frac>` has the same size, alignment and ABI as
[`", stringify!($Inner), "`]; it is `#[repr(transparent)]` with
[`", stringify!($Inner), "`] as the only non-zero-sized field.
# Examples
```rust
use fixed::{types::extra::U3, ", stringify!($Self), "};
let eleven = ", stringify!($Self), "::<U3>::from_num(11);
assert_eq!(eleven, ", stringify!($Self), "::<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, ", stringify!($Self), "::<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
[U", $n, "]: crate::types::extra::U", $n, "
[U0]: crate::types::extra::U0
[`generic_const_exprs` feature]: https://github.com/rust-lang/rust/issues/76560
[alpha version]: https://docs.rs/fixed/2.0.0-alpha/fixed/
";
#[repr(transparent)]
pub struct $Self<Frac> {
pub(crate) bits: $Inner,
phantom: PhantomData<Frac>,
}
}
impl<Frac> Clone for $Self<Frac> {
#[inline]
fn clone(&self) -> $Self<Frac> {
*self
}
}
impl<Frac> Copy for $Self<Frac> {}
impl<Frac> Default for $Self<Frac> {
#[inline]
fn default() -> Self {
$Self {
bits: Default::default(),
phantom: PhantomData,
}
}
}
impl<Frac> Hash for $Self<Frac> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.bits.hash(state);
}
}
fixed_no_frac! {
{Self, Inner} = {$Self, $Inner},
Signedness = $Signedness,
LeEqU = $LeEqU,
{Unm1, Un} = {$Unm1, $Un},
[nm4 ..= np1] = [$nm4, $nm3, $nm2, $nm1, $n, $np1],
{ISelf, IInner} = {$ISelf, $IInner},
{USelf, UInner} = {$USelf, $UInner},
nbytes = $nbytes,
{bytes_val, rev_bytes_val} = {$bytes_val, $rev_bytes_val},
{be_bytes, le_bytes} = {$be_bytes, $le_bytes},
$(
n2 = $n2,
{Double, DoubleInner} = {$Double, $DoubleInner},
{IDouble, IDoubleInner} = {$IDouble, $IDoubleInner},
)?
}
fixed_frac! {
{Self, Inner} = {$Self, $Inner},
Signedness = $Signedness,
LeEqU = $LeEqU,
{nm4, nm1, n} = {$nm4, $nm1, $n},
{USelf, UInner} = {$USelf, $UInner},
NonZeroUInner = $NonZeroUInner,
}
fixed_const! {
Self = $Self,
Signedness = $Signedness,
LeEqU = $LeEqU,
[nm4 ..= n] = [$nm4, $nm3, $nm2, $nm1, $n],
[LeEqUC0 ..= LeEqUC3] = [$LeEqUC0, $LeEqUC1, $LeEqUC2, $LeEqUC3],
}
};
}
fixed! {
description = "An eight",
{Self, Inner} = {FixedU8, u8},
Signedness = Unsigned,
LeEqU = LeEqU8,
{Unm1, Un} = {U7, U8},
[nm4 ..= np1] = [4, 5, 6, 7, 8, 9],
{ISelf, IInner} = {FixedI8, i8},
{USelf, UInner} = {FixedU8, u8},
NonZeroUInner = NonZeroU8,
[LeEqUC0 ..= LeEqUC3] = [U8, U7, U6, U5],
nbytes = 1,
{bytes_val, rev_bytes_val} = {"0x12", "0x12"},
{be_bytes, le_bytes} = {"[0x12]", "[0x12]"},
n2 = 16,
{Double, DoubleInner} = {FixedU16, u16},
{IDouble, IDoubleInner} = {FixedI16, i16},
}
fixed! {
description = "A 16",
{Self, Inner} = {FixedU16, u16},
Signedness = Unsigned,
LeEqU = LeEqU16,
{Unm1, Un} = {U15, U16},
[nm4 ..= np1] = [12, 13, 14, 15, 16, 17],
{ISelf, IInner} = {FixedI16, i16},
{USelf, UInner} = {FixedU16, u16},
NonZeroUInner = NonZeroU16,
[LeEqUC0 ..= LeEqUC3] = [U16, U15, U14, U13],
nbytes = 2,
{bytes_val, rev_bytes_val} = {"0x1234", "0x3412"},
{be_bytes, le_bytes} = {"[0x12, 0x34]", "[0x34, 0x12]"},
n2 = 32,
{Double, DoubleInner} = {FixedU32, u32},
{IDouble, IDoubleInner} = {FixedI32, i32},
}
fixed! {
description = "A 32",
{Self, Inner} = {FixedU32, u32},
Signedness = Unsigned,
LeEqU = LeEqU32,
{Unm1, Un} = {U31, U32},
[nm4 ..= np1] = [28, 29, 30, 31, 32, 33],
{ISelf, IInner} = {FixedI32, i32},
{USelf, UInner} = {FixedU32, u32},
NonZeroUInner = NonZeroU32,
[LeEqUC0 ..= LeEqUC3] = [U32, U31, U30, U29],
nbytes = 4,
{bytes_val, rev_bytes_val} = {"0x1234_5678", "0x7856_3412"},
{be_bytes, le_bytes} = {"[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]"},
n2 = 64,
{Double, DoubleInner} = {FixedU64, u64},
{IDouble, IDoubleInner} = {FixedI64, i64},
}
fixed! {
description = "A 64",
{Self, Inner} = {FixedU64, u64},
Signedness = Unsigned,
LeEqU = LeEqU64,
{Unm1, Un} = {U63, U64},
[nm4 ..= np1] = [60, 61, 62, 63, 64, 65],
{ISelf, IInner} = {FixedI64, i64},
{USelf, UInner} = {FixedU64, u64},
NonZeroUInner = NonZeroU64,
[LeEqUC0 ..= LeEqUC3] = [U64, U63, U62, U61],
nbytes = 8,
{bytes_val, rev_bytes_val} = {"0x1234_5678_9ABC_DE0F", "0x0FDE_BC9A_7856_3412"},
{be_bytes, le_bytes} = {
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0x0F]",
"[0x0F, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
},
n2 = 128,
{Double, DoubleInner} = {FixedU128, u128},
{IDouble, IDoubleInner} = {FixedI128, i128},
}
fixed! {
description = "A 128",
{Self, Inner} = {FixedU128, u128},
Signedness = Unsigned,
LeEqU = LeEqU128,
{Unm1, Un} = {U127, U128},
[nm4 ..= np1] = [124, 125, 126, 127, 128, 129],
{ISelf, IInner} = {FixedI128, i128},
{USelf, UInner} = {FixedU128, u128},
NonZeroUInner = NonZeroU128,
[LeEqUC0 ..= LeEqUC3] = [U128, U127, U126, U125],
nbytes = 16,
{bytes_val, rev_bytes_val} = {
"0x1234_5678_9ABC_DEF0_0102_0304_0506_0708",
"0x0807_0605_0403_0201_F0DE_BC9A_7856_3412",
},
{be_bytes, le_bytes} = {
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, \
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]",
"[0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, \
0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
},
}
fixed! {
description = "An eight",
{Self, Inner} = {FixedI8, i8},
Signedness = Signed,
LeEqU = LeEqU8,
{Unm1, Un} = {U7, U8},
[nm4 ..= np1] = [4, 5, 6, 7, 8, 9],
{ISelf, IInner} = {FixedI8, i8},
{USelf, UInner} = {FixedU8, u8},
NonZeroUInner = NonZeroU8,
[LeEqUC0 ..= LeEqUC3] = [U7, U6, U5, U4],
nbytes = 1,
{bytes_val, rev_bytes_val} = {"0x12", "0x12"},
{be_bytes, le_bytes} = {"[0x12]", "[0x12]"},
n2 = 16,
{Double, DoubleInner} = {FixedI16, i16},
{IDouble, IDoubleInner} = {FixedI16, i16},
}
fixed! {
description = "A 16",
{Self, Inner} = {FixedI16, i16},
Signedness = Signed,
LeEqU = LeEqU16,
{Unm1, Un} = {U15, U16},
[nm4 ..= np1] = [12, 13, 14, 15, 16, 17],
{ISelf, IInner} = {FixedI16, i16},
{USelf, UInner} = {FixedU16, u16},
NonZeroUInner = NonZeroU16,
[LeEqUC0 ..= LeEqUC3] = [U15, U14, U13, U12],
nbytes = 2,
{bytes_val, rev_bytes_val} = {"0x1234", "0x3412"},
{be_bytes, le_bytes} = {"[0x12, 0x34]", "[0x34, 0x12]"},
n2 = 32,
{Double, DoubleInner} = {FixedI32, i32},
{IDouble, IDoubleInner} = {FixedI32, i32},
}
fixed! {
description = "A 32",
{Self, Inner} = {FixedI32, i32},
Signedness = Signed,
LeEqU = LeEqU32,
{Unm1, Un} = {U31, U32},
[nm4 ..= np1] = [28, 29, 30, 31, 32, 33],
{ISelf, IInner} = {FixedI32, i32},
{USelf, UInner} = {FixedU32, u32},
NonZeroUInner = NonZeroU32,
[LeEqUC0 ..= LeEqUC3] = [U31, U30, U29, U28],
nbytes = 4,
{bytes_val, rev_bytes_val} = {"0x1234_5678", "0x7856_3412"},
{be_bytes, le_bytes} = {"[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]"},
n2 = 64,
{Double, DoubleInner} = {FixedI64, i64},
{IDouble, IDoubleInner} = {FixedI64, i64},
}
fixed! {
description = "A 64",
{Self, Inner} = {FixedI64, i64},
Signedness = Signed,
LeEqU = LeEqU64,
{Unm1, Un} = {U63, U64},
[nm4 ..= np1] = [60, 61, 62, 63, 64, 65],
{ISelf, IInner} = {FixedI64, i64},
{USelf, UInner} = {FixedU64, u64},
NonZeroUInner = NonZeroU64,
[LeEqUC0 ..= LeEqUC3] = [U63, U62, U61, U60],
nbytes = 8,
{bytes_val, rev_bytes_val} = {"0x1234_5678_9ABC_DE0F", "0x0FDE_BC9A_7856_3412"},
{be_bytes, le_bytes} = {
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0x0F]",
"[0x0F, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
},
n2 = 128,
{Double, DoubleInner} = {FixedI128, i128},
{IDouble, IDoubleInner} = {FixedI128, i128},
}
fixed! {
description = "A 128",
{Self, Inner} = {FixedI128, i128},
Signedness = Signed,
LeEqU = LeEqU128,
{Unm1, Un} = {U127, U128},
[nm4 ..= np1] = [124, 125, 126, 127, 128, 129],
{ISelf, IInner} = {FixedI128, i128},
{USelf, UInner} = {FixedU128, u128},
NonZeroUInner = NonZeroU128,
[LeEqUC0 ..= LeEqUC3] = [U127, U126, U125, U124],
nbytes = 16,
{bytes_val, rev_bytes_val} = {
"0x1234_5678_9ABC_DEF0_0102_0304_0506_0708",
"0x0807_0605_0403_0201_F0DE_BC9A_7856_3412",
},
{be_bytes, le_bytes} = {
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, \
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]",
"[0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, \
0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
},
}
#[deprecated(since = "1.18.0", note = "use `F128` instead")]
#[repr(transparent)]
#[derive(Clone, Copy, Default, Hash, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct F128Bits(pub u128);
#[allow(deprecated)]
impl F128Bits {
#[inline]
pub(crate) fn to_bits(self) -> u128 {
self.0
}
#[inline]
pub(crate) fn from_bits(bits: u128) -> F128Bits {
F128Bits(bits)
}
}
#[macro_export]
#[deprecated(since = "1.20.0", note = "use the `const_from_int` method instead")]
macro_rules! const_fixed_from_int {
($($vis:vis const $NAME:ident: $Fixed:ty = $int:expr;)*) => { $(
$vis const $NAME: $Fixed = <$Fixed>::const_from_int($int);
)* };
}
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::ZERO, false));
assert_eq!(f.overflowing_floor(), (I0F32::ZERO, true));
assert_eq!(f.overflowing_round(), (I0F32::ZERO, true));
assert_eq!(f.overflowing_round_ties_even(), (I0F32::ZERO, 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::ZERO, false));
assert_eq!(f.overflowing_floor(), (I0F32::ZERO, true));
assert_eq!(f.overflowing_round(), (I0F32::ZERO, false));
assert_eq!(f.overflowing_round_ties_even(), (I0F32::ZERO, 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::ZERO, false));
assert_eq!(f.overflowing_floor(), (I0F32::ZERO, false));
assert_eq!(f.overflowing_round(), (I0F32::ZERO, false));
assert_eq!(f.overflowing_round_ties_even(), (I0F32::ZERO, 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::ZERO, true));
assert_eq!(f.overflowing_floor(), (I0F32::ZERO, false));
assert_eq!(f.overflowing_round(), (I0F32::ZERO, false));
assert_eq!(f.overflowing_round_ties_even(), (I0F32::ZERO, 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::NEG_ONE, false));
assert_eq!(f.overflowing_floor(), (I1F31::NEG_ONE, false));
assert_eq!(f.overflowing_round(), (I1F31::NEG_ONE, false));
assert_eq!(f.overflowing_round_ties_even(), (I1F31::NEG_ONE, 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::ZERO, false));
assert_eq!(f.overflowing_floor(), (I1F31::NEG_ONE, false));
assert_eq!(f.overflowing_round(), (I1F31::NEG_ONE, false));
assert_eq!(f.overflowing_round_ties_even(), (I1F31::NEG_ONE, 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::ZERO, false));
assert_eq!(f.overflowing_floor(), (I1F31::NEG_ONE, false));
assert_eq!(f.overflowing_round(), (I1F31::NEG_ONE, false));
assert_eq!(f.overflowing_round_ties_even(), (I1F31::ZERO, 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::ZERO, false));
assert_eq!(f.overflowing_floor(), (I1F31::NEG_ONE, false));
assert_eq!(f.overflowing_round(), (I1F31::ZERO, false));
assert_eq!(f.overflowing_round_ties_even(), (I1F31::ZERO, 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::NEG_ONE, true));
assert_eq!(f.overflowing_floor(), (I1F31::ZERO, false));
assert_eq!(f.overflowing_round(), (I1F31::ZERO, false));
assert_eq!(f.overflowing_round_ties_even(), (I1F31::ZERO, 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::NEG_ONE, true));
assert_eq!(f.overflowing_floor(), (I1F31::ZERO, false));
assert_eq!(f.overflowing_round(), (I1F31::NEG_ONE, true));
assert_eq!(f.overflowing_round_ties_even(), (I1F31::ZERO, 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::ZERO, false));
assert_eq!(f.overflowing_floor(), (I1F31::ZERO, false));
assert_eq!(f.overflowing_round(), (I1F31::ZERO, false));
assert_eq!(f.overflowing_round_ties_even(), (I1F31::ZERO, 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::NEG_ONE, true));
assert_eq!(f.overflowing_floor(), (I1F31::ZERO, false));
assert_eq!(f.overflowing_round(), (I1F31::NEG_ONE, true));
assert_eq!(f.overflowing_round_ties_even(), (I1F31::NEG_ONE, 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_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_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_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_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_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_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::NEG_ONE, false));
assert_eq!(f.overflowing_floor(), (I16F16::NEG_ONE, false));
assert_eq!(f.overflowing_round(), (I16F16::NEG_ONE, false));
assert_eq!(f.overflowing_round_ties_even(), (I16F16::NEG_ONE, 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::ZERO, false));
assert_eq!(f.overflowing_floor(), (I16F16::NEG_ONE, false));
assert_eq!(f.overflowing_round(), (I16F16::NEG_ONE, false));
assert_eq!(f.overflowing_round_ties_even(), (I16F16::NEG_ONE, 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::ZERO, false));
assert_eq!(f.overflowing_floor(), (I16F16::NEG_ONE, false));
assert_eq!(f.overflowing_round(), (I16F16::NEG_ONE, false));
assert_eq!(f.overflowing_round_ties_even(), (I16F16::ZERO, 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::ZERO, false));
assert_eq!(f.overflowing_floor(), (I16F16::NEG_ONE, false));
assert_eq!(f.overflowing_round(), (I16F16::ZERO, false));
assert_eq!(f.overflowing_round_ties_even(), (I16F16::ZERO, 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::ZERO, false));
assert_eq!(f.overflowing_floor(), (I16F16::ZERO, false));
assert_eq!(f.overflowing_round(), (I16F16::ZERO, false));
assert_eq!(f.overflowing_round_ties_even(), (I16F16::ZERO, 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::ONE, false));
assert_eq!(f.overflowing_floor(), (I16F16::ZERO, false));
assert_eq!(f.overflowing_round(), (I16F16::ZERO, false));
assert_eq!(f.overflowing_round_ties_even(), (I16F16::ZERO, 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::ONE, false));
assert_eq!(f.overflowing_floor(), (I16F16::ZERO, false));
assert_eq!(f.overflowing_round(), (I16F16::ONE, false));
assert_eq!(f.overflowing_round_ties_even(), (I16F16::ZERO, 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::ONE, false));
assert_eq!(f.overflowing_floor(), (I16F16::ZERO, false));
assert_eq!(f.overflowing_round(), (I16F16::ONE, false));
assert_eq!(f.overflowing_round_ties_even(), (I16F16::ONE, 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::ONE, false));
assert_eq!(f.overflowing_floor(), (I16F16::ONE, false));
assert_eq!(f.overflowing_round(), (I16F16::ONE, false));
assert_eq!(f.overflowing_round_ties_even(), (I16F16::ONE, 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_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_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_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_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_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_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::ZERO, false));
assert_eq!(f.overflowing_floor(), (U0F32::ZERO, false));
assert_eq!(f.overflowing_round(), (U0F32::ZERO, false));
assert_eq!(f.overflowing_round_ties_even(), (U0F32::ZERO, 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::ZERO, true));
assert_eq!(f.overflowing_floor(), (U0F32::ZERO, false));
assert_eq!(f.overflowing_round(), (U0F32::ZERO, false));
assert_eq!(f.overflowing_round_ties_even(), (U0F32::ZERO, 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::ZERO, true));
assert_eq!(f.overflowing_floor(), (U0F32::ZERO, false));
assert_eq!(f.overflowing_round(), (U0F32::ZERO, true));
assert_eq!(f.overflowing_round_ties_even(), (U0F32::ZERO, 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::ZERO, true));
assert_eq!(f.overflowing_floor(), (U0F32::ZERO, false));
assert_eq!(f.overflowing_round(), (U0F32::ZERO, true));
assert_eq!(f.overflowing_round_ties_even(), (U0F32::ZERO, 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::ZERO, false));
assert_eq!(f.overflowing_floor(), (U16F16::ZERO, false));
assert_eq!(f.overflowing_round(), (U16F16::ZERO, false));
assert_eq!(f.overflowing_round_ties_even(), (U16F16::ZERO, 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::ONE, false));
assert_eq!(f.overflowing_floor(), (U16F16::ZERO, false));
assert_eq!(f.overflowing_round(), (U16F16::ZERO, false));
assert_eq!(f.overflowing_round_ties_even(), (U16F16::ZERO, 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::ONE, false));
assert_eq!(f.overflowing_floor(), (U16F16::ZERO, false));
assert_eq!(f.overflowing_round(), (U16F16::ONE, false));
assert_eq!(f.overflowing_round_ties_even(), (U16F16::ZERO, 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::ONE, false));
assert_eq!(f.overflowing_floor(), (U16F16::ZERO, false));
assert_eq!(f.overflowing_round(), (U16F16::ONE, false));
assert_eq!(f.overflowing_round_ties_even(), (U16F16::ONE, 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::ONE, false));
assert_eq!(f.overflowing_floor(), (U16F16::ONE, false));
assert_eq!(f.overflowing_round(), (U16F16::ONE, false));
assert_eq!(f.overflowing_round_ties_even(), (U16F16::ONE, 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_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_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_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_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_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_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::ZERO, 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::ZERO, true)
);
assert_eq!(I1F31::NEG_ONE.overflowing_recip(), (I1F31::NEG_ONE, false));
}
#[test]
fn wide_mul_mixed() {
let s = I16F16::MAX;
let u = U16F16::MAX >> 1u32;
let t = U16F16::from_bits(s.to_bits() as u32);
let v = I16F16::from_bits(u.to_bits() as i32);
assert_eq!(s.wide_mul_unsigned(u).to_bits(), 0x3FFF_FFFF_0000_0001);
assert_eq!(t.wide_mul(u).to_bits(), 0x3FFF_FFFF_0000_0001);
assert_eq!(s.wide_mul(v).to_bits(), 0x3FFF_FFFF_0000_0001);
assert_eq!(s.wide_mul_unsigned(u), u.wide_mul_signed(s));
assert_eq!(t.wide_mul(u), u.wide_mul(t));
assert_eq!(s.wide_mul(v), v.wide_mul(s));
let s = I16F16::MAX;
let u = !(U16F16::MAX >> 1u32);
let t = U16F16::from_bits(s.to_bits() as u32);
let v = I16F16::from_bits(u.to_bits() as i32);
assert_eq!(s.wide_mul_unsigned(u).to_bits(), 0x3FFF_FFFF_8000_0000);
assert_eq!(t.wide_mul(u).to_bits(), 0x3FFF_FFFF_8000_0000);
assert_eq!(s.wide_mul(v).to_bits(), -0x3FFF_FFFF_8000_0000);
assert_eq!(s.wide_mul_unsigned(u), u.wide_mul_signed(s));
assert_eq!(t.wide_mul(u), u.wide_mul(t));
assert_eq!(s.wide_mul(v), v.wide_mul(s));
let s = I16F16::MAX;
let u = U16F16::MAX;
let t = U16F16::from_bits(s.to_bits() as u32);
let v = I16F16::from_bits(u.to_bits() as i32);
assert_eq!(s.wide_mul_unsigned(u).to_bits(), 0x7FFF_FFFE_8000_0001);
assert_eq!(t.wide_mul(u).to_bits(), 0x7FFF_FFFE_8000_0001);
assert_eq!(s.wide_mul(v).to_bits(), -0x0000_0000_7FFF_FFFF);
assert_eq!(s.wide_mul_unsigned(u), u.wide_mul_signed(s));
assert_eq!(t.wide_mul(u), u.wide_mul(t));
assert_eq!(s.wide_mul(v), v.wide_mul(s));
let s = I16F16::MIN;
let u = U16F16::MAX >> 1u32;
let t = U16F16::from_bits(s.to_bits() as u32);
let v = I16F16::from_bits(u.to_bits() as i32);
assert_eq!(s.wide_mul_unsigned(u).to_bits(), -0x3FFF_FFFF_8000_0000);
assert_eq!(t.wide_mul(u).to_bits(), 0x3FFF_FFFF_8000_0000);
assert_eq!(s.wide_mul(v).to_bits(), -0x3FFF_FFFF_8000_0000);
assert_eq!(s.wide_mul_unsigned(u), u.wide_mul_signed(s));
assert_eq!(t.wide_mul(u), u.wide_mul(t));
assert_eq!(s.wide_mul(v), v.wide_mul(s));
let s = I16F16::MIN;
let u = !(U16F16::MAX >> 1u32);
let t = U16F16::from_bits(s.to_bits() as u32);
let v = I16F16::from_bits(u.to_bits() as i32);
assert_eq!(s.wide_mul_unsigned(u).to_bits(), -0x4000_0000_0000_0000);
assert_eq!(t.wide_mul(u).to_bits(), 0x4000_0000_0000_0000);
assert_eq!(s.wide_mul(v).to_bits(), 0x4000_0000_0000_0000);
assert_eq!(s.wide_mul_unsigned(u), u.wide_mul_signed(s));
assert_eq!(t.wide_mul(u), u.wide_mul(t));
assert_eq!(s.wide_mul(v), v.wide_mul(s));
let s = I16F16::MIN;
let u = U16F16::MAX;
let t = U16F16::from_bits(s.to_bits() as u32);
let v = I16F16::from_bits(u.to_bits() as i32);
assert_eq!(s.wide_mul_unsigned(u).to_bits(), -0x7FFF_FFFF_8000_0000);
assert_eq!(t.wide_mul(u).to_bits(), 0x7FFF_FFFF_8000_0000);
assert_eq!(s.wide_mul(v).to_bits(), 0x8000_0000);
assert_eq!(s.wide_mul_unsigned(u), u.wide_mul_signed(s));
assert_eq!(t.wide_mul(u), u.wide_mul(t));
assert_eq!(s.wide_mul(v), v.wide_mul(s));
let s = -I16F16::DELTA;
let u = U16F16::MAX >> 1u32;
let t = U16F16::from_bits(s.to_bits() as u32);
let v = I16F16::from_bits(u.to_bits() as i32);
assert_eq!(s.wide_mul_unsigned(u).to_bits(), -0x0000_0000_7FFF_FFFF);
assert_eq!(t.wide_mul(u).to_bits(), 0x7FFF_FFFE_8000_0001);
assert_eq!(s.wide_mul(v).to_bits(), -0x0000_0000_7FFF_FFFF);
assert_eq!(s.wide_mul_unsigned(u), u.wide_mul_signed(s));
assert_eq!(t.wide_mul(u), u.wide_mul(t));
assert_eq!(s.wide_mul(v), v.wide_mul(s));
let s = -I16F16::DELTA;
let u = !(U16F16::MAX >> 1u32);
let t = U16F16::from_bits(s.to_bits() as u32);
let v = I16F16::from_bits(u.to_bits() as i32);
assert_eq!(s.wide_mul_unsigned(u).to_bits(), -0x0000_0000_8000_0000);
assert_eq!(t.wide_mul(u).to_bits(), 0x7FFF_FFFF_8000_0000);
assert_eq!(s.wide_mul(v).to_bits(), 0x0000_0000_8000_0000);
assert_eq!(s.wide_mul_unsigned(u), u.wide_mul_signed(s));
assert_eq!(t.wide_mul(u), u.wide_mul(t));
assert_eq!(s.wide_mul(v), v.wide_mul(s));
let s = -I16F16::DELTA;
let u = U16F16::MAX;
let t = U16F16::from_bits(s.to_bits() as u32);
let v = I16F16::from_bits(u.to_bits() as i32);
assert_eq!(s.wide_mul_unsigned(u).to_bits(), -0x0000_0000_FFFF_FFFF);
assert_eq!(t.wide_mul(u).to_bits(), 0xFFFF_FFFE_0000_0001);
assert_eq!(s.wide_mul(v).to_bits(), 0x0000_0000_0000_0001);
assert_eq!(s.wide_mul_unsigned(u), u.wide_mul_signed(s));
assert_eq!(t.wide_mul(u), u.wide_mul(t));
assert_eq!(s.wide_mul(v), v.wide_mul(s));
}
}