add div_euclid and rem_euclid

This commit is contained in:
Trevor Spiteri 2020-02-12 13:48:35 +01:00
parent c2fa7448c2
commit 6e93affa0d
4 changed files with 105 additions and 6 deletions

View File

@ -72,12 +72,16 @@ The conversions supported cover the following cases.
* [`Rem`] and [`RemAssign`] were implemented for fixed-point * [`Rem`] and [`RemAssign`] were implemented for fixed-point
numbers. numbers.
* The method [`checked_rem`] was added to all fixed-point types and * The following methods were added to all fixed-point types and to
to the [`Fixed`] trait. the [`Fixed`] trait:
* [`checked_rem`]
* [`div_euclid`], [`rem_euclid`]
[`checked_rem`]: https://docs.rs/fixed/0.5.3/fixed/struct.FixedI32.html#method.checked_rem
[`Rem`]: https://doc.rust-lang.org/nightly/core/ops/trait.Rem.html
[`RemAssign`]: https://doc.rust-lang.org/nightly/core/ops/trait.RemAssign.html [`RemAssign`]: https://doc.rust-lang.org/nightly/core/ops/trait.RemAssign.html
[`Rem`]: https://doc.rust-lang.org/nightly/core/ops/trait.Rem.html
[`checked_rem`]: https://docs.rs/fixed/0.5.3/fixed/struct.FixedI32.html#method.checked_rem
[`div_euclid`]: https://docs.rs/fixed/0.5.3/fixed/struct.FixedI32.html#method.div_euclid
[`rem_euclid`]: https://docs.rs/fixed/0.5.3/fixed/struct.FixedI32.html#method.rem_euclid
### Version 0.5.2 news (2020-02-02) ### Version 0.5.2 news (2020-02-02)

View File

@ -9,8 +9,10 @@ Version 0.5.3 (unreleased)
========================== ==========================
* `Rem` and `RemAssign` were implemented for fixed-point numbers. * `Rem` and `RemAssign` were implemented for fixed-point numbers.
* The method `checked_rem` was added to all fixed-point types and to * The following methods were added to all fixed-point types and to
the `Fixed` trait. the `Fixed` trait:
* `checked_rem`
* `div_euclid`, `rem_euclid`x
Version 0.5.2 (2020-02-02) Version 0.5.2 (2020-02-02)
========================== ==========================

View File

@ -137,6 +137,83 @@ assert_eq!(Fix::from_num(-5).signum(), -1);
} }
} }
comment! {
"Euclidean division.
# Panics
Panics if the divisor is zero",
if_signed_else_empty_str! {
$Signedness,
" or if the division results in overflow",
},
".
# Examples
```rust
use fixed::{types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
assert_eq!(Fix::from_num(7.5).div_euclid(Fix::from_num(2)), Fix::from_num(3));
",
if_signed_else_empty_str! {
$Signedness,
"assert_eq!(Fix::from_num(-7.5).div_euclid(Fix::from_num(2)), Fix::from_num(-4));
",
},
"```
";
#[inline]
pub fn div_euclid(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
let q = (self / rhs).round_to_zero();
if_signed! {
$Signedness;
if (self % rhs).is_negative() {
return if rhs.is_positive() {
q - Self::from_num(1)
} else {
q + Self::from_num(1)
};
}
}
q
}
}
comment! {
"Remainder for Euclidean division.
# Panics
Panics if the divisor is zero.
# Examples
```rust
use fixed::{types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
assert_eq!(Fix::from_num(7.5).rem_euclid(Fix::from_num(2)), Fix::from_num(1.5));
",
if_signed_else_empty_str! {
$Signedness,
"assert_eq!(Fix::from_num(-7.5).rem_euclid(Fix::from_num(2)), Fix::from_num(0.5));
",
},
"```
";
#[inline]
pub fn rem_euclid(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
let r = self % rhs;
if_signed! {
$Signedness;
if r.is_negative() {
return r + rhs.abs();
}
}
r
}
}
comment! { comment! {
"Checked multiplication. Returns the product, or [`None`] on overflow. "Checked multiplication. Returns the product, or [`None`] on overflow.

View File

@ -590,6 +590,20 @@ where
/// Shifts to the right by `n` bits, wrapping the truncated bits to the left end. /// Shifts to the right by `n` bits, wrapping the truncated bits to the left end.
fn rotate_right(self, n: u32) -> Self; fn rotate_right(self, n: u32) -> Self;
/// Euclidean division by an integer.
///
/// # Panics
///
/// Panics if the divisor is zero or if the division results in overflow.
fn div_euclid(self, rhs: Self) -> Self;
/// Remainder for Euclidean division.
///
/// # Panics
///
/// Panics if the divisor is zero.
fn rem_euclid(self, rhs: Self) -> Self;
/// Euclidean division by an integer. /// Euclidean division by an integer.
/// ///
/// # Panics /// # Panics
@ -1525,6 +1539,8 @@ macro_rules! impl_fixed {
trait_delegate! { fn trailing_zeros(self) -> u32 } trait_delegate! { fn trailing_zeros(self) -> u32 }
trait_delegate! { fn rotate_left(self, n: u32) -> Self } trait_delegate! { fn rotate_left(self, n: u32) -> Self }
trait_delegate! { fn rotate_right(self, n: u32) -> Self } trait_delegate! { fn rotate_right(self, n: u32) -> Self }
trait_delegate! { fn div_euclid(self, rhs: Self) -> Self }
trait_delegate! { fn rem_euclid(self, rhs: Self) -> Self }
trait_delegate! { fn div_euclid_int(self, rhs: Self::Bits) -> Self } trait_delegate! { fn div_euclid_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn rem_euclid_int(self, rhs: Self::Bits) -> Self } trait_delegate! { fn rem_euclid_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn checked_neg(self) -> Option<Self> } trait_delegate! { fn checked_neg(self) -> Option<Self> }