macro_rules! fixed_round {
(
Self = $Self:ident,
Signedness = $Signedness:ident,
n = $n:literal,
) => {
comment! {
"Returns the integer part.
",
if_signed_unsigned!(
$Signedness,
concat!(
"Note that since the numbers are stored in two’s
complement, negative numbers with non-zero fractional parts will be
rounded towards −∞, except in the case where there are no integer
bits, that is `", stringify!($Self), "<U", $n, ">`, where the return value is always zero.",
),
"Note that for unsigned numbers, this is equivalent to [`floor`].",
),
"
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
// 0010.0000
let two = Fix::from_num(2);
// 0010.0100
let two_and_quarter = two + two / 8;
assert_eq!(two_and_quarter.int(), two);
",
if_signed_else_empty_str! {
$Signedness;
"// 1101.0000
let three = Fix::from_num(3);
// 1101.1100
assert_eq!((-two_and_quarter).int(), -three);
",
},
"```
",
if_unsigned_else_empty_str! {
$Signedness;
"
[`floor`]: Self::floor
"
};
#[inline]
#[must_use]
pub const fn int(self) -> $Self<Frac> {
Self::from_bits(self.to_bits() & Self::INT_MASK)
}
}
comment! {
"Returns the fractional part.
",
if_signed_else_empty_str! {
$Signedness;
"Note that since the numbers are stored in two’s
complement, the returned fraction will be non-negative for negative
numbers, except in the case where there are no integer bits, that is
`", stringify!($Self), "<U", $n, ">` where the return value is always equal to
`self`.
",
},
"# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
// 0000.0100
let quarter = Fix::ONE / 4;
// 0010.0100
let two_and_quarter = quarter * 9;
assert_eq!(two_and_quarter.frac(), quarter);
",
if_signed_else_empty_str! {
$Signedness;
"// 0000.1100
let three_quarters = quarter * 3;
// 1101.1100
assert_eq!((-two_and_quarter).frac(), three_quarters);
",
},
"```
";
#[inline]
#[must_use]
pub const fn frac(self) -> $Self<Frac> {
Self::from_bits(self.to_bits() & Self::FRAC_MASK)
}
}
comment! {
"Rounds to the next integer towards 0.
",
if_signed_unsigned!(
$Signedness,
"Note that for negative numbers, this is different
from truncating/discarding the fractional bits. This is because in
two’s-complement representations, the value of all the bits except for
the most significant bit is positive; discarding positive bits would
round towards −∞ unlike this method which rounds towards zero.",
"Note that for unsigned numbers, this is equivalent to [`floor`].",
),
"
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.1).round_to_zero(), Fix::from_num(2));
assert_eq!(Fix::from_num(2.9).round_to_zero(), Fix::from_num(2));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.1).round_to_zero(), Fix::from_num(-2));
assert_eq!(Fix::from_num(-2.9).round_to_zero(), Fix::from_num(-2));
",
},
"```
",
if_unsigned_else_empty_str! {
$Signedness;
"
[`floor`]: Self::floor
"
};
#[inline]
#[must_use]
pub const fn round_to_zero(self) -> $Self<Frac> {
if_signed! {
$Signedness;
if self.is_negative() && self.frac().to_bits() != 0 {
let int_bits = self.int().to_bits();
let increment = Self::INT_LSB;
if Self::INT_NBITS == 1 {
return Self::from_bits(int_bits - increment);
}
return Self::from_bits(int_bits + increment);
}
}
self.int()
}
}
comment! {
"Rounds to the next integer towards +∞.
# Panics
When debug assertions are enabled, panics if the result does not fit.
When debug assertions are not enabled, the wrapped result can be
returned, but it is not considered a breaking change if in the future
it panics; if wrapping is required use [`wrapping_ceil`] instead.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).ceil(), Fix::from_num(3));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).ceil(), Fix::from_num(-2));
",
},
"```
[`wrapping_ceil`]: Self::wrapping_ceil
";
#[inline]
#[track_caller]
#[must_use]
pub const fn ceil(self) -> $Self<Frac> {
let (ceil, overflow) = self.overflowing_ceil();
debug_assert!(!overflow, "overflow");
let _ = overflow;
ceil
}
}
comment! {
"Rounds to the next integer towards −∞.
",
if_signed_else_empty_str! {
$Signedness;
"# Panics
When debug assertions are enabled, panics if the result does not fit.
When debug assertions are not enabled, the wrapped result can be
returned, but it is not considered a breaking change if in the future
it panics; if wrapping is required use [`wrapping_floor`] instead.
Overflow can only occur when there are zero integer bits.
",
},
"# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).floor(), Fix::from_num(2));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).floor(), Fix::from_num(-3));
",
},
"```
[`wrapping_floor`]: Self::wrapping_floor
";
#[inline]
#[track_caller]
#[must_use]
pub const fn floor(self) -> $Self<Frac> {
let (floor, overflow) = self.overflowing_floor();
debug_assert!(!overflow, "overflow");
let _ = overflow;
floor
}
}
comment! {
"Rounds to the nearest integer, with ties rounded away
from zero.
# Panics
When debug assertions are enabled, panics if the result does not fit.
When debug assertions are not enabled, the wrapped result can be
returned, but it is not considered a breaking change if in the future
it panics; if wrapping is required use [`wrapping_round`] instead.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).round(), Fix::from_num(3));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).round(), Fix::from_num(-3));
",
},
"```
[`wrapping_round`]: Self::wrapping_round
";
#[inline]
#[track_caller]
#[must_use]
pub const fn round(self) -> $Self<Frac> {
let (round, overflow) = self.overflowing_round();
debug_assert!(!overflow, "overflow");
let _ = overflow;
round
}
}
comment! {
"Rounds to the nearest integer, with ties rounded to even.
# Panics
When debug assertions are enabled, panics if the result does not fit.
When debug assertions are not enabled, the wrapped result can be
returned, but it is not considered a breaking change if in the future
it panics; if wrapping is required use [`wrapping_round_ties_to_even`]
instead.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).round_ties_to_even(), Fix::from_num(2));
assert_eq!(Fix::from_num(3.5).round_ties_to_even(), Fix::from_num(4));
```
[`wrapping_round_ties_to_even`]: Self::wrapping_round_ties_to_even
";
#[inline]
#[track_caller]
#[must_use]
#[doc(alias("round_ties_even"))]
pub const fn round_ties_to_even(self) -> $Self<Frac> {
let (round, overflow) = self.overflowing_round_ties_to_even();
debug_assert!(!overflow, "overflow");
let _ = overflow;
round
}
}
comment! {
"Checked ceil. Rounds to the next integer towards +∞,
returning [`None`] on overflow.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).checked_ceil(), Some(Fix::from_num(3)));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).checked_ceil(), Some(Fix::from_num(-2)));
",
},
"assert!(Fix::MAX.checked_ceil().is_none());
```
";
#[inline]
#[must_use]
pub const fn checked_ceil(self) -> Option<$Self<Frac>> {
let (ceil, overflow) = self.overflowing_ceil();
if overflow { None } else { Some(ceil) }
}
}
comment! {
"Checked floor. Rounds to the next integer towards −∞. ",
if_signed_unsigned!(
$Signedness,
"Returns [`None`] on overflow.
Overflow can only occur when there are zero integer bits.",
"Always returns [`Some`] for unsigned values.",
),
"
# Examples
```rust
use fixed::{",
if_signed_unsigned!(
$Signedness,
concat!(
"
types::extra::{U4, U", $n, "},
", stringify!($Self), ",
",
),
concat!("types::extra::U4, ", stringify!($Self)),
),
"};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).checked_floor(), Some(Fix::from_num(2)));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).checked_floor(), Some(Fix::from_num(-3)));
type AllFrac = ", stringify!($Self), "<U", $n, ">;
assert!(AllFrac::MIN.checked_floor().is_none());
",
},
"```
";
#[inline]
#[must_use]
pub const fn checked_floor(self) -> Option<$Self<Frac>> {
let (floor, overflow) = self.overflowing_floor();
if overflow { None } else { Some(floor) }
}
}
comment! {
"Checked round. Rounds to the nearest integer, with ties
rounded away from zero, returning [`None`] on overflow.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).checked_round(), Some(Fix::from_num(3)));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).checked_round(), Some(Fix::from_num(-3)));
",
},
"assert!(Fix::MAX.checked_round().is_none());
```
";
#[inline]
#[must_use]
pub const fn checked_round(self) -> Option<$Self<Frac>> {
let (round, overflow) = self.overflowing_round();
if overflow { None } else { Some(round) }
}
}
comment! {
"Checked round. Rounds to the nearest integer, with ties
rounded to even, returning [`None`] on overflow.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).checked_round_ties_to_even(), Some(Fix::from_num(2)));
assert_eq!(Fix::from_num(3.5).checked_round_ties_to_even(), Some(Fix::from_num(4)));
assert!(Fix::MAX.checked_round_ties_to_even().is_none());
```
";
#[inline]
#[must_use]
pub const fn checked_round_ties_to_even(self) -> Option<$Self<Frac>> {
let (round, overflow) = self.overflowing_round_ties_to_even();
if overflow { None } else { Some(round) }
}
}
comment! {
"Saturating ceil. Rounds to the next integer towards +∞,
saturating on overflow.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).saturating_ceil(), Fix::from_num(3));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).saturating_ceil(), Fix::from_num(-2));
",
},
"assert_eq!(Fix::MAX.saturating_ceil(), Fix::MAX);
```
";
#[inline]
#[must_use]
pub const fn saturating_ceil(self) -> $Self<Frac> {
let (ceil, overflow) = self.overflowing_ceil();
if overflow { Self::MAX } else { ceil }
}
}
comment! {
"Saturating floor. Rounds to the next integer towards −∞",
if_signed_unsigned!(
$Signedness,
", saturating on overflow.
Overflow can only occur when there are zero integer bits.",
". Cannot overflow for unsigned values.",
),
"
# Examples
```rust
use fixed::{",
if_signed_unsigned!(
$Signedness,
concat!(
"
types::extra::{U4, U", $n, "},
", stringify!($Self), ",
",
),
concat!("types::extra::U4, ", stringify!($Self)),
),
"};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).saturating_floor(), Fix::from_num(2));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).saturating_floor(), Fix::from_num(-3));
type AllFrac = ", stringify!($Self), "<U", $n, ">;
assert_eq!(AllFrac::MIN.saturating_floor(), AllFrac::MIN);
",
},
"```
";
#[inline]
#[must_use]
pub const fn saturating_floor(self) -> $Self<Frac> {
let (floor, overflow) = self.overflowing_floor();
if overflow { Self::MIN } else { floor }
}
}
comment! {
"Saturating round. Rounds to the nearest integer, with
ties rounded away from zero, and saturating on overflow.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).saturating_round(), Fix::from_num(3));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).saturating_round(), Fix::from_num(-3));
",
},
"assert_eq!(Fix::MAX.saturating_round(), Fix::MAX);
```
";
#[inline]
#[must_use]
pub const fn saturating_round(self) -> $Self<Frac> {
let saturated = if self.to_bits() > 0 {
$Self::MAX
} else {
$Self::MIN
};
let (round, overflow) = self.overflowing_round();
if overflow { saturated } else { round }
}
}
comment! {
"Saturating round. Rounds to the nearest integer, with
ties rounded to even, and saturating on overflow.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).saturating_round_ties_to_even(), Fix::from_num(2));
assert_eq!(Fix::from_num(3.5).saturating_round_ties_to_even(), Fix::from_num(4));
assert_eq!(Fix::MAX.saturating_round_ties_to_even(), Fix::MAX);
```
";
#[inline]
#[must_use]
pub const fn saturating_round_ties_to_even(self) -> $Self<Frac> {
let saturated = if self.to_bits() > 0 {
$Self::MAX
} else {
$Self::MIN
};
let (round, overflow) = self.overflowing_round_ties_to_even();
if overflow { saturated } else { round }
}
}
comment! {
"Wrapping ceil. Rounds to the next integer towards +∞,
wrapping on overflow.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).wrapping_ceil(), Fix::from_num(3));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).wrapping_ceil(), Fix::from_num(-2));
",
},
"assert_eq!(Fix::MAX.wrapping_ceil(), Fix::MIN);
```
";
#[inline]
#[must_use]
pub const fn wrapping_ceil(self) -> $Self<Frac> {
self.overflowing_ceil().0
}
}
comment! {
"Wrapping floor. Rounds to the next integer towards −∞",
if_signed_unsigned!(
$Signedness,
", wrapping on overflow.
Overflow can only occur when there are zero integer bits.",
". Cannot overflow for unsigned values.",
),
"
# Examples
```rust
use fixed::{",
if_signed_unsigned!(
$Signedness,
concat!(
"
types::extra::{U4, U", $n, "},
", stringify!($Self), ",
",
),
concat!("types::extra::U4, ", stringify!($Self)),
),
"};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).wrapping_floor(), Fix::from_num(2));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).wrapping_floor(), Fix::from_num(-3));
type AllFrac = ", stringify!($Self), "<U", $n, ">;
assert_eq!(AllFrac::MIN.wrapping_floor(), AllFrac::ZERO);
",
},
"```
";
#[inline]
#[must_use]
pub const fn wrapping_floor(self) -> $Self<Frac> {
self.overflowing_floor().0
}
}
comment! {
"Wrapping round. Rounds to the next integer to the
nearest, with ties rounded away from zero, and wrapping on overflow.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).wrapping_round(), Fix::from_num(3));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).wrapping_round(), Fix::from_num(-3));
",
},
"assert_eq!(Fix::MAX.wrapping_round(), Fix::MIN);
```
";
#[inline]
#[must_use]
pub const fn wrapping_round(self) -> $Self<Frac> {
self.overflowing_round().0
}
}
comment! {
"Wrapping round. Rounds to the next integer to the
nearest, with ties rounded to even, and wrapping on overflow.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).wrapping_round_ties_to_even(), Fix::from_num(2));
assert_eq!(Fix::from_num(3.5).wrapping_round_ties_to_even(), Fix::from_num(4));
assert_eq!(Fix::MAX.wrapping_round_ties_to_even(), Fix::MIN);
```
";
#[inline]
#[must_use]
pub const fn wrapping_round_ties_to_even(self) -> $Self<Frac> {
self.overflowing_round_ties_to_even().0
}
}
comment! {
"Unwrapped ceil. Rounds to the next integer towards +∞,
panicking on overflow.
# Panics
Panics if the result does not fit.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).unwrapped_ceil(), Fix::from_num(3));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).unwrapped_ceil(), Fix::from_num(-2));
",
},
"```
The following panics because of overflow.
```should_panic
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
let _overflow = Fix::MAX.unwrapped_ceil();
```
";
#[inline]
#[track_caller]
#[must_use]
pub const fn unwrapped_ceil(self) -> $Self<Frac> {
match self.checked_ceil() {
Some(s) => s,
None => panic!("overflow"),
}
}
}
comment! {
"Unwrapped floor. Rounds to the next integer towards −∞",
if_signed_unsigned!(
$Signedness,
", panicking on overflow.
Overflow can only occur when there are zero integer bits.
# Panics
Panics if the result does not fit.",
". Cannot overflow for unsigned values.",
),
"
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).unwrapped_floor(), Fix::from_num(2));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).unwrapped_floor(), Fix::from_num(-3));
```
The following panics because of overflow.
```should_panic
use fixed::{types::extra::U", $n, ", ", stringify!($Self), "};
type AllFrac = ", stringify!($Self), "<U", $n, ">;
let _overflow = AllFrac::MIN.unwrapped_floor();
",
},
"```
";
#[inline]
#[track_caller]
#[must_use]
pub const fn unwrapped_floor(self) -> $Self<Frac> {
match self.checked_floor() {
Some(s) => s,
None => panic!("overflow"),
}
}
}
comment! {
"Unwrapped round. Rounds to the next integer to the
nearest, with ties rounded away from zero, and panicking on overflow.
# Panics
Panics if the result does not fit.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).unwrapped_round(), Fix::from_num(3));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).unwrapped_round(), Fix::from_num(-3));
",
},
"```
The following panics because of overflow.
```should_panic
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
let _overflow = Fix::MAX.unwrapped_round();
```
";
#[inline]
#[track_caller]
#[must_use]
pub const fn unwrapped_round(self) -> $Self<Frac> {
match self.checked_round() {
Some(s) => s,
None => panic!("overflow"),
}
}
}
comment! {
"Unwrapped round. Rounds to the next integer to the
nearest, with ties rounded to even, and panicking on overflow.
# Panics
Panics if the result does not fit.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).unwrapped_round_ties_to_even(), Fix::from_num(2));
assert_eq!(Fix::from_num(3.5).unwrapped_round_ties_to_even(), Fix::from_num(4));
```
The following panics because of overflow.
```should_panic
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
let _overflow = Fix::MAX.unwrapped_round_ties_to_even();
```
";
#[inline]
#[track_caller]
#[must_use]
pub const fn unwrapped_round_ties_to_even(self) -> $Self<Frac> {
match self.checked_round_ties_to_even() {
Some(s) => s,
None => panic!("overflow"),
}
}
}
comment! {
"Overflowing ceil. Rounds to the next integer towards +∞.
Returns a [tuple] of the fixed-point number and a [`bool`], indicating
whether an overflow has occurred. On overflow, the wrapped value is
returned.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).overflowing_ceil(), (Fix::from_num(3), false));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).overflowing_ceil(), (Fix::from_num(-2), false));
"
},
"assert_eq!(Fix::MAX.overflowing_ceil(), (Fix::MIN, true));
```
";
#[inline]
#[must_use]
pub const fn overflowing_ceil(self) -> ($Self<Frac>, bool) {
let int = self.int();
if self.frac().to_bits() == 0 {
return (int, false);
}
if Self::INT_NBITS == 0 {
return (int, self.to_bits() > 0);
}
let increment = Self::from_bits(Self::INT_LSB);
if_signed! {
$Signedness;
if Self::INT_NBITS == 1 {
return int.overflowing_sub(increment);
}
}
int.overflowing_add(increment)
}
}
comment! {
"Overflowing floor. Rounds to the next integer towards −∞.
Returns a [tuple] of the fixed-point number and
",
if_signed_unsigned!(
$Signedness,
"a [`bool`], indicating whether an overflow has
occurred. On overflow, the wrapped value isreturned. Overflow can only
occur when there are zero integer bits.",
"[`false`].",
),
"
# Examples
```rust
use fixed::{",
if_signed_unsigned!(
$Signedness,
concat!(
"
types::extra::{U4, U", $n, "},
", stringify!($Self), ",
",
),
concat!("types::extra::U4, ", stringify!($Self)),
),
"};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).overflowing_floor(), (Fix::from_num(2), false));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).overflowing_floor(), (Fix::from_num(-3), false));
type AllFrac = ", stringify!($Self), "<U", $n, ">;
assert_eq!(AllFrac::MIN.overflowing_floor(), (AllFrac::ZERO, true));
",
},
"```
";
#[inline]
#[must_use]
pub const fn overflowing_floor(self) -> ($Self<Frac>, bool) {
let int = self.int();
if_signed! {
$Signedness;
if Self::INT_NBITS == 0 {
return (int, self.to_bits() < 0);
}
}
(int, false)
}
}
comment! {
"Overflowing round. Rounds to the next integer to the
nearest, with ties rounded away from zero.
Returns a [tuple] of the fixed-point number and a [`bool`] indicating
whether an overflow has occurred. On overflow, the wrapped value is
returned.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).overflowing_round(), (Fix::from_num(3), false));
",
if_signed_else_empty_str! {
$Signedness;
"assert_eq!(Fix::from_num(-2.5).overflowing_round(), (Fix::from_num(-3), false));
",
},
"assert_eq!(Fix::MAX.overflowing_round(), (Fix::MIN, true));
```
";
#[inline]
#[must_use]
pub const fn overflowing_round(self) -> ($Self<Frac>, bool) {
let int = self.int();
if (self.to_bits() & Self::FRAC_MSB) == 0 {
return (int, false);
}
let increment = Self::from_bits(Self::INT_LSB);
if_signed! {
$Signedness;
let tie = self.frac().to_bits() == Self::FRAC_MSB;
if Self::INT_NBITS == 0 {
return (int, tie);
}
if tie && self.to_bits() < 0 {
return (int, false);
}
if Self::INT_NBITS == 1 {
return int.overflowing_sub(increment);
}
int.overflowing_add(increment)
}
if_unsigned! {
$Signedness;
if Self::INT_NBITS == 0 {
return (int, true);
}
int.overflowing_add(increment)
}
}
}
comment! {
"Overflowing round. Rounds to the next integer to the
nearest, with ties rounded to even.
Returns a [tuple] of the fixed-point number and a [`bool`] indicating
whether an overflow has occurred. On overflow, the wrapped value is
returned.
# Examples
```rust
use fixed::{types::extra::U4, ", stringify!($Self), "};
type Fix = ", stringify!($Self), "<U4>;
assert_eq!(Fix::from_num(2.5).overflowing_round_ties_to_even(), (Fix::from_num(2), false));
assert_eq!(Fix::from_num(3.5).overflowing_round_ties_to_even(), (Fix::from_num(4), false));
assert_eq!(Fix::MAX.overflowing_round_ties_to_even(), (Fix::MIN, true));
```
";
#[inline]
#[must_use]
pub const fn overflowing_round_ties_to_even(self) -> ($Self<Frac>, bool) {
let int = self.int();
if (self.to_bits() & Self::FRAC_MSB) == 0 {
return (int, false);
}
if self.frac().to_bits() == Self::FRAC_MSB && (int.to_bits() & Self::INT_LSB) == 0 {
return (int, false);
}
let increment = Self::from_bits(Self::INT_LSB);
if_signed! {
$Signedness;
if Self::INT_NBITS == 1 {
int.overflowing_sub(increment)
} else {
int.overflowing_add(increment)
}
}
if_unsigned! {
$Signedness;
if Self::INT_NBITS == 0 {
return (int, true);
}
int.overflowing_add(increment)
}
}
}
};
}