#![cfg_attr(not(feature = "std"), no_std)]
#![warn(missing_docs)]
#![warn(unsafe_op_in_unsafe_fn)]
#![doc(html_root_url = "https://docs.rs/fixed/2.0.0-alpha.12")]
#![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))]
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
#[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 fixed_from_bits;
mod float_helper;
mod from_str;
mod helpers;
#[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;
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::{
traits::{FromFixed, ToFixed},
types::extra::{If, True},
};
use core::hash::{Hash, Hasher};
use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8};
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:ident, $s_nbits:expr,
$s_nbits_p1:expr, $s_nbits_m1:expr, $s_nbits_m2:expr, $s_nbits_m3:expr, $s_nbits_m4:expr
),
$nbytes:expr, $nbits:expr, $nbits_m1:expr,
$bytes_val:expr, $rev_bytes_val:expr, $be_bytes:expr, $le_bytes:expr,
$IFixed:ident, $UFixed:ident,
$IInner:ident, $UInner:ident, $NonZeroUInner:ident, $Signedness:tt,
$nbits_cm3:expr, $nbits_cm2:expr, $nbits_cm1:expr,
$nbits_c0:expr, $nbits_c1:expr, $nbits_c2:expr, $nbits_c3:expr,
$HasDouble:tt, $s_nbits_2:expr,
$Double:ident, $DoubleInner:ty, $IDouble:ident, $IDoubleInner:ty
) => {
fixed! {
$description,
$Fixed[stringify!($Fixed)](
$Inner[stringify!($Inner)], $s_nbits,
$s_nbits_p1, $s_nbits_m1, $s_nbits_m2, $s_nbits_m3, $s_nbits_m4
),
$nbytes, $nbits, $nbits_m1,
$bytes_val, $rev_bytes_val, $be_bytes, $le_bytes,
$IFixed[stringify!($IFixed)], $UFixed[stringify!($UFixed)],
$IInner, $UInner, $NonZeroUInner, $Signedness,
$nbits_cm3, $nbits_cm2, $nbits_cm1, $nbits_c0, $nbits_c1, $nbits_c2, $nbits_c3,
$HasDouble, $s_nbits_2,
$Double[stringify!($Double)], $DoubleInner, $IDouble, $IDoubleInner
}
};
(
$description:expr,
$Fixed:ident[$s_fixed:expr](
$Inner:ident[$s_inner:expr], $s_nbits:expr,
$s_nbits_p1:expr, $s_nbits_m1:expr, $s_nbits_m2:expr, $s_nbits_m3:expr, $s_nbits_m4:expr
),
$nbytes:expr, $nbits:expr, $nbits_m1:expr,
$bytes_val:expr, $rev_bytes_val:expr, $be_bytes:expr, $le_bytes:expr,
$IFixed:ident[$s_ifixed:expr], $UFixed:ident[$s_ufixed:expr],
$IInner:ident, $UInner:ident, $NonZeroUInner:ident, $Signedness:tt,
$nbits_cm3:expr, $nbits_cm2:expr, $nbits_cm1:expr,
$nbits_c0:expr, $nbits_c1:expr, $nbits_c2:expr, $nbits_c3:expr,
$HasDouble:tt, $s_nbits_2:expr,
$Double:ident[$s_double:expr], $DoubleInner:ty, $IDouble:ident, $IDoubleInner:ty
) => {
comment! {
$description, "-bit ",
if_signed_unsigned!($Signedness, "signed", "unsigned"),
" number with `FRAC` fractional bits.
The number has ", $s_nbits, " bits, of which <i>f</i> = `FRAC` are
fractional bits and ", $s_nbits, " − <i>f</i> are integer bits.
The value <i>x</i> can lie in the range ",
if_signed_unsigned!(
$Signedness,
concat!("−2<sup>", $s_nbits_m1, "</sup>/2<sup><i>f</i></sup>"),
"0",
),
" ≤ <i>x</i> < 2<sup>",
if_signed_unsigned!($Signedness, $s_nbits_m1, $s_nbits),
"</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>", $s_fixed, "\\<0></code>, <i>f</i> = 0 and
<i>Δ</i> = 1, and the fixed-point number behaves like ",
if_signed_unsigned!($Signedness, "an", "a"),
" [`", $s_inner, "`] with the value lying in the range ",
if_signed_unsigned!(
$Signedness,
concat!("−2<sup>", $s_nbits_m1, "</sup>"),
"0",
),
" ≤ <i>x</i> < 2<sup>",
if_signed_unsigned!($Signedness, $s_nbits_m1, $s_nbits),
"</sup>. For <code>", $s_fixed, "\\<", $s_nbits, "></code>,
<i>f</i> = ", $s_nbits, " and
<i>Δ</i> = 1/2<sup>", $s_nbits, "</sup>, and the value lies in the
range ",
if_signed_unsigned!(
$Signedness,
"−1/2 ≤ <i>x</i> < 1/2",
"0 ≤ <i>x</i> < 1",
),
".
`", $s_fixed, "<FRAC>` has the same size, alignment and ABI as [`", $s_inner, "`];
it is `#[repr(transparent)]` with [`", $s_inner, "`] as the only non-zero-sized field.
# Examples
```rust
#![feature(generic_const_exprs)]
# #![allow(incomplete_features)]
use fixed::", $s_fixed, ";
let eleven = ", $s_fixed, "::<3>::from_num(11);
assert_eq!(eleven, ", $s_fixed, "::<3>::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, "::<3>::from_bits(11 << 1));
assert_eq!(two_point_75, 2.75);
assert_eq!(two_point_75.to_string(), \"2.8\");
```
";
#[repr(transparent)]
pub struct $Fixed<const FRAC: i32> {
pub(crate) bits: $Inner,
}
}
impl<const FRAC: i32> Clone for $Fixed<FRAC> {
#[inline]
fn clone(&self) -> $Fixed<FRAC> {
*self
}
}
impl<const FRAC: i32> Copy for $Fixed<FRAC> {}
impl<const FRAC: i32> Default for $Fixed<FRAC> {
#[inline]
fn default() -> Self {
$Fixed {
bits: Default::default(),
}
}
}
impl<const FRAC: i32> 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], $s_nbits, $s_nbits_p1, $s_nbits_m1, $s_nbits_m2, $s_nbits_m3
),
$nbytes, $nbits, $nbits_m1, $bytes_val, $rev_bytes_val, $be_bytes, $le_bytes,
$IFixed[$s_ifixed], $UFixed[$s_ufixed],
$IInner, $UInner, $NonZeroUInner, $Signedness,
$HasDouble, $s_nbits_2,
$Double[$s_double], $DoubleInner, $IDouble, $IDoubleInner
}
fixed_frac! {
$Fixed[$s_fixed]($Inner[$s_inner], $nbits, $s_nbits, $s_nbits_m1, $s_nbits_m4),
$UFixed, $UInner, $NonZeroUInner, $Signedness
}
fixed_const! {
$Fixed[$s_fixed]($nbits, $s_nbits, $s_nbits_m1, $s_nbits_m2, $s_nbits_m3, $s_nbits_m4),
$nbits_cm3, $nbits_cm2, $nbits_cm1, $nbits_c0, $nbits_c1, $nbits_c2, $nbits_c3,
$Signedness
}
};
}
fixed! {
"An eight",
FixedU8(u8, "8", "9", "7", "6", "5", "4"),
1, 8, 7, "0x12", "0x12", "[0x12]", "[0x12]",
FixedI8, FixedU8, i8, u8, NonZeroU8, Unsigned,
11, 10, 9, 8, 7, 6, 5,
True, "16", FixedU16, u16, FixedI16, i16
}
fixed! {
"A 16",
FixedU16(u16, "16", "17", "15", "14", "13", "12"),
2, 16, 15, "0x1234", "0x3412", "[0x12, 0x34]", "[0x34, 0x12]",
FixedI16, FixedU16, i16, u16, NonZeroU16, Unsigned,
19, 18, 17, 16, 15, 14, 13,
True, "32", FixedU32, u32, FixedI32, i32
}
fixed! {
"A 32",
FixedU32(u32, "32", "33", "31", "30", "29", "28"),
4, 32, 31, "0x1234_5678", "0x7856_3412", "[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]",
FixedI32, FixedU32, i32, u32, NonZeroU32, Unsigned,
35, 34, 33, 32, 31, 30, 29,
True, "64", FixedU64, u64, FixedI64, i64
}
fixed! {
"A 64",
FixedU64(u64, "64", "65", "63", "62", "61", "60"),
8, 64, 63, "0x1234_5678_9ABC_DE0F", "0x0FDE_BC9A_7856_3412",
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0x0F]",
"[0x0F, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
FixedI64, FixedU64, i64, u64, NonZeroU64, Unsigned,
67, 66, 65, 64, 63, 62, 61,
True, "128", FixedU128, u128, FixedI128, i128
}
fixed! {
"A 128",
FixedU128(u128, "128", "129", "127", "126", "125", "124"),
16, 128, 127, "0x1234_5678_9ABC_DEF0_0102_0304_0506_0708",
"0x0807_0605_0403_0201_F0DE_BC9A_7856_3412",
"[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]",
FixedI128, FixedU128, i128, u128, NonZeroU128, Unsigned,
131, 130, 129, 128, 127, 126, 125,
False, "128", FixedU128, u128, FixedI128, i128
}
fixed! {
"An eight",
FixedI8(i8, "8", "9", "7", "6", "5", "4"),
1, 8, 7, "0x12", "0x12", "[0x12]", "[0x12]",
FixedI8, FixedU8, i8, u8, NonZeroU8, Signed,
10, 9, 8, 7, 6, 5, 4,
True, "16", FixedI16, i16, FixedI16, i16
}
fixed! {
"A 16",
FixedI16(i16, "16", "17", "15", "14", "13", "12"),
2, 16, 15, "0x1234", "0x3412", "[0x12, 0x34]", "[0x34, 0x12]",
FixedI16, FixedU16, i16, u16, NonZeroU16, Signed,
18, 17, 16, 15, 14, 13, 12,
True, "32", FixedI32, i32, FixedI32, i32
}
fixed! {
"A 32",
FixedI32(i32, "32", "33", "31", "30", "29", "28"),
4, 32, 31, "0x1234_5678", "0x7856_3412", "[0x12, 0x34, 0x56, 0x78]", "[0x78, 0x56, 0x34, 0x12]",
FixedI32, FixedU32, i32, u32, NonZeroU32, Signed,
34, 33, 32, 31, 30, 29, 28,
True, "64", FixedI64, i64, FixedI64, i64
}
fixed! {
"A 64",
FixedI64(i64, "64", "65", "63", "62", "61", "60"),
8, 64, 63, "0x1234_5678_9ABC_DE0F", "0x0FDE_BC9A_7856_3412",
"[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0x0F]",
"[0x0F, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]",
FixedI64, FixedU64, i64, u64, NonZeroU64, Signed,
66, 65, 64, 63, 62, 61, 60,
True, "128", FixedI128, i128, FixedI128, i128
}
fixed! {
"A 128",
FixedI128(i128, "128", "129", "127", "126", "125", "124"),
16, 128, 127, "0x1234_5678_9ABC_DEF0_0102_0304_0506_0708",
"0x0807_0605_0403_0201_F0DE_BC9A_7856_3412",
"[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]",
FixedI128, FixedU128, i128, u128, NonZeroU128, Signed,
130, 129, 128, 127, 126, 125, 124,
False, "128", FixedI128, i128, FixedI128, i128
}
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_to_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_to_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_to_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_to_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_to_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_to_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_to_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_to_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_to_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_to_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_to_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_to_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_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::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_to_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_to_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_to_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_to_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_to_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_to_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_to_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_to_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_to_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_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::ZERO, false));
assert_eq!(f.overflowing_floor(), (U0F32::ZERO, false));
assert_eq!(f.overflowing_round(), (U0F32::ZERO, false));
assert_eq!(f.overflowing_round_ties_to_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_to_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_to_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_to_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_to_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_to_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_to_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_to_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_to_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_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::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));
}
}