add round_to_zero

This commit is contained in:
Trevor Spiteri 2019-08-22 13:33:23 +02:00
parent 7d08654e0a
commit 9e333d99c2
6 changed files with 278 additions and 47 deletions

View File

@ -65,14 +65,16 @@ Various conversion methods are available:
* The following methods are now `const` functions:
* [`abs`], [`wrapping_abs`], [`overflowing_abs`]
* [`is_power_of_two`]
* The method [`round_to_zero`] was added.
* The method [`round_ties_to_even`] and its checked variants were
added.
[`abs`]: https://docs.rs/fixed/0.4.3/fixed/struct.FixedI32.html#method.abs
[`is_power_of_two`]: https://docs.rs/fixed/0.4.3/fixed/struct.FixedU32.html#method.is_power_of_two
[`overflowing_abs`]: https://docs.rs/fixed/0.4.3/fixed/struct.FixedI32.html#method.overflowing_abs
[`wrapping_abs`]: https://docs.rs/fixed/0.4.3/fixed/struct.FixedI32.html#method.wrapping_abs
[`round_ties_to_even`]: https://docs.rs/fixed/0.4.3/fixed/struct.FixedI32.html#method.round_ties_to_even
[`round_to_zero`]: https://docs.rs/fixed/0.4.3/fixed/struct.FixedI32.html#method.round_to_zero
[`wrapping_abs`]: https://docs.rs/fixed/0.4.3/fixed/struct.FixedI32.html#method.wrapping_abs
### Version 0.4.3 news (2019-08-20)

View File

@ -13,6 +13,7 @@ Version 0.4.4 (unreleased)
* The following methods are now `const` functions:
* `abs`, `wrapping_abs`, `overflowing_abs`
* `is_power_of_two`
* The method `round_to_zero` was added.
* The method `round_ties_to_even` and its checked variants were
added.

View File

@ -401,218 +401,326 @@ mod tests {
// -0.5
let f = I0F32::from_bits(-1 << 31);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I0F32::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I0F32::from_num(0), true));
assert_eq!(f.overflowing_round(), (I0F32::from_num(0), true));
assert_eq!(f.overflowing_round_ties_to_even(), (I0F32::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I0F32::from_num(0), false)
);
// -0.5 + Δ
let f = I0F32::from_bits((-1 << 31) + 1);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I0F32::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I0F32::from_num(0), true));
assert_eq!(f.overflowing_round(), (I0F32::from_num(0), false));
assert_eq!(f.overflowing_round_ties_to_even(), (I0F32::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I0F32::from_num(0), false)
);
// 0.5 - Δ
let f = I0F32::from_bits((1 << 30) - 1 + (1 << 30));
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I0F32::from_num(0), true));
assert_eq!(f.overflowing_floor(), (I0F32::from_num(0), false));
assert_eq!(f.overflowing_round(), (I0F32::from_num(0), false));
assert_eq!(f.overflowing_round_ties_to_even(), (I0F32::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I0F32::from_num(0), false)
);
// -0.5 - Δ
let f = I1F31::from_bits(((-1) << 30) - 1);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I1F31::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I1F31::from_num(-1), false));
assert_eq!(f.overflowing_round(), (I1F31::from_num(-1), false));
assert_eq!(f.overflowing_round_ties_to_even(), (I1F31::from_num(-1), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I1F31::from_num(-1), false)
);
// -0.5
let f = I1F31::from_bits((-1) << 30);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I1F31::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I1F31::from_num(-1), false));
assert_eq!(f.overflowing_round(), (I1F31::from_num(-1), false));
assert_eq!(f.overflowing_round_ties_to_even(), (I1F31::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I1F31::from_num(0), false)
);
// -0.5 + Δ
let f = I1F31::from_bits(((-1) << 30) + 1);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I1F31::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I1F31::from_num(-1), false));
assert_eq!(f.overflowing_round(), (I1F31::from_num(0), false));
assert_eq!(f.overflowing_round_ties_to_even(), (I1F31::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I1F31::from_num(0), false)
);
// 0.5 - Δ
let f = I1F31::from_bits((1 << 30) - 1);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I1F31::from_num(-1), true));
assert_eq!(f.overflowing_floor(), (I1F31::from_num(0), false));
assert_eq!(f.overflowing_round(), (I1F31::from_num(0), false));
assert_eq!(f.overflowing_round_ties_to_even(), (I1F31::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I1F31::from_num(0), false)
);
// 0.5
let f = I1F31::from_bits(1 << 30);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I1F31::from_num(-1), true));
assert_eq!(f.overflowing_floor(), (I1F31::from_num(0), false));
assert_eq!(f.overflowing_round(), (I1F31::from_num(-1), true));
assert_eq!(f.overflowing_round_ties_to_even(), (I1F31::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I1F31::from_num(0), false)
);
// 0.5 + Δ
let f = I1F31::from_bits((1 << 30) + 1);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I1F31::from_num(-1), true));
assert_eq!(f.overflowing_floor(), (I1F31::from_num(0), false));
assert_eq!(f.overflowing_round(), (I1F31::from_num(-1), true));
assert_eq!(f.overflowing_round_ties_to_even(), (I1F31::from_num(-1), true));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I1F31::from_num(-1), true)
);
// -3.5 - Δ
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(-4), false)
);
// -3.5
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(-4), false)
);
// -3.5 + Δ
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(-3), false)
);
// -2.5 - Δ
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(-3), false)
);
// -2.5
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(-2), false)
);
// -2.5 + Δ
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(-2), false)
);
// -0.5 - Δ
let f = I16F16::from_bits(((-1) << 15) - 1);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(-1), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(-1), false));
assert_eq!(f.overflowing_round_ties_to_even(), (I16F16::from_num(-1), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(-1), false)
);
// -0.5
let f = I16F16::from_bits((-1) << 15);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(-1), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(-1), false));
assert_eq!(f.overflowing_round_ties_to_even(), (I16F16::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(0), false)
);
// -0.5 + Δ
let f = I16F16::from_bits(((-1) << 15) + 1);
assert_eq!(f.to_num::<i32>(), -1);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(0), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(-1), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(0), false));
assert_eq!(f.overflowing_round_ties_to_even(), (I16F16::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(0), false)
);
// 0.5 - Δ
let f = I16F16::from_bits((1 << 15) - 1);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(1), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(0), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(0), false));
assert_eq!(f.overflowing_round_ties_to_even(), (I16F16::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(0), false)
);
// 0.5
let f = I16F16::from_bits(1 << 15);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(1), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(0), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(1), false));
assert_eq!(f.overflowing_round_ties_to_even(), (I16F16::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(0), false)
);
// 0.5 + Δ
let f = I16F16::from_bits((1 << 15) + 1);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (I16F16::from_num(1), false));
assert_eq!(f.overflowing_floor(), (I16F16::from_num(0), false));
assert_eq!(f.overflowing_round(), (I16F16::from_num(1), false));
assert_eq!(f.overflowing_round_ties_to_even(), (I16F16::from_num(1), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(1), false)
);
// 2.5 - Δ
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(2), false)
);
// 2.5
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(2), false)
);
// 2.5 + Δ
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(3), false)
);
// 3.5 - Δ
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(3), false)
);
// 3.5
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(4), false)
);
// 3.5 + Δ
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(I16F16::from_num(4), false)
);
}
#[test]
@ -620,97 +728,145 @@ mod tests {
// 0.5 - Δ
let f = U0F32::from_bits((1 << 31) - 1);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (U0F32::from_num(0), true));
assert_eq!(f.overflowing_floor(), (U0F32::from_num(0), false));
assert_eq!(f.overflowing_round(), (U0F32::from_num(0), false));
assert_eq!(f.overflowing_round_ties_to_even(), (U0F32::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U0F32::from_num(0), false)
);
// 0.5
let f = U0F32::from_bits(1 << 31);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (U0F32::from_num(0), true));
assert_eq!(f.overflowing_floor(), (U0F32::from_num(0), false));
assert_eq!(f.overflowing_round(), (U0F32::from_num(0), true));
assert_eq!(f.overflowing_round_ties_to_even(), (U0F32::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U0F32::from_num(0), false)
);
// 0.5 + Δ
let f = U0F32::from_bits((1 << 31) + 1);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (U0F32::from_num(0), true));
assert_eq!(f.overflowing_floor(), (U0F32::from_num(0), false));
assert_eq!(f.overflowing_round(), (U0F32::from_num(0), true));
assert_eq!(f.overflowing_round_ties_to_even(), (U0F32::from_num(0), true));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U0F32::from_num(0), true)
);
// 0.5 - Δ
let f = U16F16::from_bits((1 << 15) - 1);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (U16F16::from_num(1), false));
assert_eq!(f.overflowing_floor(), (U16F16::from_num(0), false));
assert_eq!(f.overflowing_round(), (U16F16::from_num(0), false));
assert_eq!(f.overflowing_round_ties_to_even(), (U16F16::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(0), false)
);
// 0.5
let f = U16F16::from_bits(1 << 15);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (U16F16::from_num(1), false));
assert_eq!(f.overflowing_floor(), (U16F16::from_num(0), false));
assert_eq!(f.overflowing_round(), (U16F16::from_num(1), false));
assert_eq!(f.overflowing_round_ties_to_even(), (U16F16::from_num(0), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(0), false)
);
// 0.5 + Δ
let f = U16F16::from_bits((1 << 15) + 1);
assert_eq!(f.to_num::<i32>(), 0);
assert_eq!(f.round_to_zero(), 0);
assert_eq!(f.overflowing_ceil(), (U16F16::from_num(1), false));
assert_eq!(f.overflowing_floor(), (U16F16::from_num(0), false));
assert_eq!(f.overflowing_round(), (U16F16::from_num(1), false));
assert_eq!(f.overflowing_round_ties_to_even(), (U16F16::from_num(1), false));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(1), false)
);
// 2.5 - Δ
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(2), false)
);
// 2.5
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(2), false)
);
// 2.5 + Δ
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(3), false)
);
// 3.5 - Δ
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(3), false)
);
// 3.5
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(4), false)
);
// 3.5 + Δ
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));
assert_eq!(
f.overflowing_round_ties_to_even(),
(U16F16::from_num(4), false)
);
}
}

View File

@ -47,6 +47,14 @@ macro_rules! if_signed_else_empty_str {
""
};
}
macro_rules! if_unsigned_else_empty_str {
(Signed, $($unsigned:tt)*) => {
""
};
(Unsigned, $($unsigned:tt)*) => {
concat!($($unsigned)*)
};
}
macro_rules! doc_comment {
($comment:expr; $($tt:tt)*) => {

View File

@ -19,16 +19,19 @@ macro_rules! fixed_round {
"Returns the integer part.
",
if_signed_else_empty_str! {
if_signed_unsigned! {
$Signedness,
"Note that since the numbers are stored in twos
concat!(
"Note that since the numbers are stored in twos
complement, negative numbers with non-zero fractional parts will be
rounded towards , except in the case where there are no integer
bits, that is `", $s_fixed, "<U", $s_nbits, ">`, where the return value is always zero.
",
bits, that is `", $s_fixed, "<U", $s_nbits, ">`, where the return value is always zero.",
),
"Note that for unsigned numbers, this is equivalent to [`floor`].",
},
"# Examples
"
# Examples
```rust
use fixed::{types::extra::U4, ", $s_fixed, "};
@ -48,7 +51,13 @@ assert_eq!((-two_and_quarter).int(), -three);
",
},
"```
";
",
if_unsigned_else_empty_str! {
$Signedness,
"
[`floor`]: #method.floor
"
};
#[inline]
pub fn int(self) -> $Fixed<Frac> {
Self::from_bits(self.to_bits() & Self::INT_MASK)
@ -173,6 +182,56 @@ assert_eq!(Fix::from_num(2.5).floor(), Fix::from_num(2));
}
}
comment! {
"Rounds to the next integer towards 0.
",
if_unsigned_else_empty_str! {
$Signedness,
"Note that for unsigned numbers, this is equivalent to [`floor`].
",
},
"# Examples
```rust
use fixed::{types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<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`]: #method.floor
"
};
#[inline]
pub fn round_to_zero(self) -> $Fixed<Frac> {
if_signed! {
$Signedness;
if self.is_negative() {
let int = self.int();
let increment = Self::from_bits(Self::INT_LSB);
if Self::INT_NBITS == 1 {
// increment is -1, so subtract it
return int - increment;
}
return int + increment;
}
}
self.int()
}
}
comment! {
"Rounds to the nearest integer, with ties rounded away
from zero.
@ -653,6 +712,7 @@ assert_eq!(Fix::from_num(2.5).overflowing_ceil(), (Fix::from_num(3), false));
if_signed! {
$Signedness;
if Self::INT_NBITS == 1 {
// increment is -1, so subtract it
return int.overflowing_sub(increment);
}
}

View File

@ -418,6 +418,9 @@ where
/// Rounds to the next integer towards −∞.
fn floor(self) -> Self;
/// Rounds to the next integer towards 0.
fn round_to_zero(self) -> Self;
/// Rounds to the nearest integer, with ties rounded away from zero.
fn round(self) -> Self;
@ -1474,6 +1477,7 @@ macro_rules! impl_fixed {
trait_delegate! { fn frac(self) -> Self }
trait_delegate! { fn ceil(self) -> Self }
trait_delegate! { fn floor(self) -> Self }
trait_delegate! { fn round_to_zero(self) -> Self }
trait_delegate! { fn round(self) -> Self }
trait_delegate! { fn round_ties_to_even(self) -> Self }
trait_delegate! { fn checked_ceil(self) -> Option<Self> }