add {saturating,wrapping,overflowing}_div_euclid
This commit is contained in:
parent
43926daa62
commit
bf7c2024e1
|
@ -77,6 +77,9 @@ The conversions supported cover the following cases.
|
||||||
* [`checked_rem`]
|
* [`checked_rem`]
|
||||||
* [`div_euclid`], [`rem_euclid`]
|
* [`div_euclid`], [`rem_euclid`]
|
||||||
* [`checked_div_euclid`], [`checked_rem_euclid`]
|
* [`checked_div_euclid`], [`checked_rem_euclid`]
|
||||||
|
* [`saturating_div_euclid`]
|
||||||
|
* [`wrapping_div_euclid`]
|
||||||
|
* [`overflowing_div_euclid`]
|
||||||
|
|
||||||
[`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
|
[`Rem`]: https://doc.rust-lang.org/nightly/core/ops/trait.Rem.html
|
||||||
|
@ -84,7 +87,10 @@ The conversions supported cover the following cases.
|
||||||
[`checked_rem_euclid`]: https://docs.rs/fixed/0.5.3/fixed/struct.FixedI32.html#method.checked_rem_euclid
|
[`checked_rem_euclid`]: https://docs.rs/fixed/0.5.3/fixed/struct.FixedI32.html#method.checked_rem_euclid
|
||||||
[`checked_rem`]: https://docs.rs/fixed/0.5.3/fixed/struct.FixedI32.html#method.checked_rem
|
[`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
|
[`div_euclid`]: https://docs.rs/fixed/0.5.3/fixed/struct.FixedI32.html#method.div_euclid
|
||||||
|
[`overflowing_div_euclid`]: https://docs.rs/fixed/0.5.3/fixed/struct.FixedI32.html#method.overflowing_div_euclid
|
||||||
[`rem_euclid`]: https://docs.rs/fixed/0.5.3/fixed/struct.FixedI32.html#method.rem_euclid
|
[`rem_euclid`]: https://docs.rs/fixed/0.5.3/fixed/struct.FixedI32.html#method.rem_euclid
|
||||||
|
[`saturating_div_euclid`]: https://docs.rs/fixed/0.5.3/fixed/struct.FixedI32.html#method.saturating_div_euclid
|
||||||
|
[`wrapping_div_euclid`]: https://docs.rs/fixed/0.5.3/fixed/struct.FixedI32.html#method.wrapping_div_euclid
|
||||||
|
|
||||||
### Version 0.5.2 news (2020-02-02)
|
### Version 0.5.2 news (2020-02-02)
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,10 @@ Version 0.5.3 (unreleased)
|
||||||
the `Fixed` trait:
|
the `Fixed` trait:
|
||||||
* `checked_rem`
|
* `checked_rem`
|
||||||
* `div_euclid`, `rem_euclid`
|
* `div_euclid`, `rem_euclid`
|
||||||
* `checked_div_euclid`, `checked_rem_euclid`
|
* `checked_div_euclid`, `checked_rem_euclid`
|
||||||
|
* `saturating_div_euclid`
|
||||||
|
* `wrapping_div_euclid`
|
||||||
|
* `overflowing_div_euclid`
|
||||||
|
|
||||||
Version 0.5.2 (2020-02-02)
|
Version 0.5.2 (2020-02-02)
|
||||||
==========================
|
==========================
|
||||||
|
|
|
@ -324,6 +324,47 @@ assert_eq!(Fix::max_value().saturating_div(one_half), Fix::max_value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
comment! {
|
||||||
|
"Saturating Euclidean division. Returns the quotient,
|
||||||
|
saturating on overflow.
|
||||||
|
|
||||||
|
# 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).saturating_div_euclid(Fix::from_num(2)), Fix::from_num(3));
|
||||||
|
assert_eq!(Fix::max_value().saturating_div_euclid(Fix::from_num(0.25)), Fix::max_value());
|
||||||
|
",
|
||||||
|
if_signed_else_empty_str! {
|
||||||
|
$Signedness,
|
||||||
|
"assert_eq!(Fix::from_num(-7.5).saturating_div_euclid(Fix::from_num(2)), Fix::from_num(-4));
|
||||||
|
assert_eq!(Fix::min_value().saturating_div_euclid(Fix::from_num(0.25)), Fix::min_value());
|
||||||
|
",
|
||||||
|
},
|
||||||
|
"```
|
||||||
|
|
||||||
|
[`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
|
||||||
|
";
|
||||||
|
#[inline]
|
||||||
|
pub fn saturating_div_euclid(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
|
||||||
|
if rhs.to_bits() == 0 {
|
||||||
|
panic!("division by zero");
|
||||||
|
}
|
||||||
|
self.checked_div_euclid(rhs).unwrap_or_else(|| {
|
||||||
|
if (self.to_bits() > 0) == (rhs.to_bits() > 0) {
|
||||||
|
Self::max_value()
|
||||||
|
} else {
|
||||||
|
Self::min_value()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
comment! {
|
comment! {
|
||||||
"Wrapping multiplication. Returns the product, wrapping on overflow.
|
"Wrapping multiplication. Returns the product, wrapping on overflow.
|
||||||
|
|
||||||
|
@ -370,6 +411,29 @@ assert_eq!(Fix::max_value().wrapping_div(quarter), wrapped);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
comment! {
|
||||||
|
"Wrapping Euclidean division. Returns the quotient, wrapping on overflow.
|
||||||
|
|
||||||
|
# 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).wrapping_div_euclid(Fix::from_num(2)), Fix::from_num(3));
|
||||||
|
let wrapped = Fix::max_value().wrapping_mul_int(4).round_to_zero();
|
||||||
|
assert_eq!(Fix::max_value().wrapping_div_euclid(Fix::from_num(0.25)), wrapped);
|
||||||
|
```
|
||||||
|
";
|
||||||
|
#[inline]
|
||||||
|
pub fn wrapping_div_euclid(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
|
||||||
|
self.overflowing_div_euclid(rhs).0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
comment! {
|
comment! {
|
||||||
"Overflowing multiplication.
|
"Overflowing multiplication.
|
||||||
|
|
||||||
|
@ -417,6 +481,9 @@ let quarter = Fix::from_num(1) / 4;
|
||||||
let wrapped = Fix::from_bits(!0 << 2);
|
let wrapped = Fix::from_bits(!0 << 2);
|
||||||
assert_eq!(Fix::max_value().overflowing_div(quarter), (wrapped, true));
|
assert_eq!(Fix::max_value().overflowing_div(quarter), (wrapped, true));
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
|
||||||
|
[tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
|
||||||
";
|
";
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn overflowing_div(self, rhs: $Fixed<Frac>) -> ($Fixed<Frac>, bool) {
|
pub fn overflowing_div(self, rhs: $Fixed<Frac>) -> ($Fixed<Frac>, bool) {
|
||||||
|
@ -424,6 +491,52 @@ assert_eq!(Fix::max_value().overflowing_div(quarter), (wrapped, true));
|
||||||
(Self::from_bits(ans), overflow)
|
(Self::from_bits(ans), overflow)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
comment! {
|
||||||
|
"Overflowing Euclidean division.
|
||||||
|
|
||||||
|
Returns a [tuple] of the quotient and a [`bool`] indicating whether an
|
||||||
|
overflow has occurred. On overflow, the wrapped value is returned.
|
||||||
|
|
||||||
|
# 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).overflowing_div_euclid(Fix::from_num(2)), (Fix::from_num(3), false));
|
||||||
|
let wrapped = Fix::max_value().wrapping_mul_int(4).round_to_zero();
|
||||||
|
assert_eq!(Fix::max_value().overflowing_div_euclid(Fix::from_num(0.25)), (wrapped, true));
|
||||||
|
```
|
||||||
|
|
||||||
|
[`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
|
||||||
|
[tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
|
||||||
|
";
|
||||||
|
#[inline]
|
||||||
|
pub fn overflowing_div_euclid(self, rhs: $Fixed<Frac>) -> ($Fixed<Frac>, bool) {
|
||||||
|
let (mut q, overflow) = self.overflowing_div(rhs);
|
||||||
|
q = q.round_to_zero();
|
||||||
|
if_signed! {
|
||||||
|
$Signedness;
|
||||||
|
if (self % rhs).is_negative() {
|
||||||
|
let one = match Self::checked_from_num(1) {
|
||||||
|
None => return (q, true),
|
||||||
|
Some(one) => one,
|
||||||
|
};
|
||||||
|
let (q, overflow2) = if rhs.is_positive() {
|
||||||
|
q.overflowing_sub(one)
|
||||||
|
} else {
|
||||||
|
q.overflowing_add(one)
|
||||||
|
};
|
||||||
|
return (q, overflow | overflow2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(q, overflow)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -728,6 +728,13 @@ where
|
||||||
/// Panics if the divisor is zero.
|
/// Panics if the divisor is zero.
|
||||||
fn saturating_div(self, rhs: Self) -> Self;
|
fn saturating_div(self, rhs: Self) -> Self;
|
||||||
|
|
||||||
|
/// Saturating Euclidean division. Returns the quotient, saturating on overflow.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the divisor is zero.
|
||||||
|
fn saturating_div_euclid(self, rhs: Self) -> Self;
|
||||||
|
|
||||||
/// Saturating multiplication by an integer. Returns the product, saturating on overflow.
|
/// Saturating multiplication by an integer. Returns the product, saturating on overflow.
|
||||||
fn saturating_mul_int(self, rhs: Self::Bits) -> Self;
|
fn saturating_mul_int(self, rhs: Self::Bits) -> Self;
|
||||||
|
|
||||||
|
@ -750,6 +757,13 @@ where
|
||||||
/// Panics if the divisor is zero.
|
/// Panics if the divisor is zero.
|
||||||
fn wrapping_div(self, rhs: Self) -> Self;
|
fn wrapping_div(self, rhs: Self) -> Self;
|
||||||
|
|
||||||
|
/// Wrapping Euclidean division. Returns the quotient, wrapping on overflow.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the divisor is zero.
|
||||||
|
fn wrapping_div_euclid(self, rhs: Self) -> Self;
|
||||||
|
|
||||||
/// Wrapping multiplication by an integer. Returns the product, wrapping on overflow.
|
/// Wrapping multiplication by an integer. Returns the product, wrapping on overflow.
|
||||||
fn wrapping_mul_int(self, rhs: Self::Bits) -> Self;
|
fn wrapping_mul_int(self, rhs: Self::Bits) -> Self;
|
||||||
|
|
||||||
|
@ -854,6 +868,20 @@ where
|
||||||
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
|
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
|
||||||
fn overflowing_div(self, rhs: Self) -> (Self, bool);
|
fn overflowing_div(self, rhs: Self) -> (Self, bool);
|
||||||
|
|
||||||
|
/// Overflowing Euclidean division.
|
||||||
|
///
|
||||||
|
/// Returns a [tuple] of the quotient and a [`bool`], indicating
|
||||||
|
/// whether an overflow has occurred. On overflow, the wrapped
|
||||||
|
/// value is returned.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the divisor is zero.
|
||||||
|
///
|
||||||
|
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
|
||||||
|
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
|
||||||
|
fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool);
|
||||||
|
|
||||||
/// Overflowing multiplication by an integer.
|
/// Overflowing multiplication by an integer.
|
||||||
///
|
///
|
||||||
/// Returns a [tuple] of the product and a [`bool`], indicating
|
/// Returns a [tuple] of the product and a [`bool`], indicating
|
||||||
|
@ -1576,12 +1604,14 @@ macro_rules! impl_fixed {
|
||||||
trait_delegate! { fn saturating_sub(self, rhs: Self) -> Self }
|
trait_delegate! { fn saturating_sub(self, rhs: Self) -> Self }
|
||||||
trait_delegate! { fn saturating_mul(self, rhs: Self) -> Self }
|
trait_delegate! { fn saturating_mul(self, rhs: Self) -> Self }
|
||||||
trait_delegate! { fn saturating_div(self, rhs: Self) -> Self }
|
trait_delegate! { fn saturating_div(self, rhs: Self) -> Self }
|
||||||
|
trait_delegate! { fn saturating_div_euclid(self, rhs: Self) -> Self }
|
||||||
trait_delegate! { fn saturating_mul_int(self, rhs: Self::Bits) -> Self }
|
trait_delegate! { fn saturating_mul_int(self, rhs: Self::Bits) -> Self }
|
||||||
trait_delegate! { fn wrapping_neg(self) -> Self }
|
trait_delegate! { fn wrapping_neg(self) -> Self }
|
||||||
trait_delegate! { fn wrapping_add(self, rhs: Self) -> Self }
|
trait_delegate! { fn wrapping_add(self, rhs: Self) -> Self }
|
||||||
trait_delegate! { fn wrapping_sub(self, rhs: Self) -> Self }
|
trait_delegate! { fn wrapping_sub(self, rhs: Self) -> Self }
|
||||||
trait_delegate! { fn wrapping_mul(self, rhs: Self) -> Self }
|
trait_delegate! { fn wrapping_mul(self, rhs: Self) -> Self }
|
||||||
trait_delegate! { fn wrapping_div(self, rhs: Self) -> Self }
|
trait_delegate! { fn wrapping_div(self, rhs: Self) -> Self }
|
||||||
|
trait_delegate! { fn wrapping_div_euclid(self, rhs: Self) -> Self }
|
||||||
trait_delegate! { fn wrapping_mul_int(self, rhs: Self::Bits) -> Self }
|
trait_delegate! { fn wrapping_mul_int(self, rhs: Self::Bits) -> Self }
|
||||||
trait_delegate! { fn wrapping_div_int(self, rhs: Self::Bits) -> Self }
|
trait_delegate! { fn wrapping_div_int(self, rhs: Self::Bits) -> Self }
|
||||||
trait_delegate! { fn wrapping_rem_int(self, rhs: Self::Bits) -> Self }
|
trait_delegate! { fn wrapping_rem_int(self, rhs: Self::Bits) -> Self }
|
||||||
|
@ -1594,6 +1624,7 @@ macro_rules! impl_fixed {
|
||||||
trait_delegate! { fn overflowing_sub(self, rhs: Self) -> (Self, bool) }
|
trait_delegate! { fn overflowing_sub(self, rhs: Self) -> (Self, bool) }
|
||||||
trait_delegate! { fn overflowing_mul(self, rhs: Self) -> (Self, bool) }
|
trait_delegate! { fn overflowing_mul(self, rhs: Self) -> (Self, bool) }
|
||||||
trait_delegate! { fn overflowing_div(self, rhs: Self) -> (Self, bool) }
|
trait_delegate! { fn overflowing_div(self, rhs: Self) -> (Self, bool) }
|
||||||
|
trait_delegate! { fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) }
|
||||||
trait_delegate! { fn overflowing_mul_int(self, rhs: Self::Bits) -> (Self, bool) }
|
trait_delegate! { fn overflowing_mul_int(self, rhs: Self::Bits) -> (Self, bool) }
|
||||||
trait_delegate! { fn overflowing_div_int(self, rhs: Self::Bits) -> (Self, bool) }
|
trait_delegate! { fn overflowing_div_int(self, rhs: Self::Bits) -> (Self, bool) }
|
||||||
trait_delegate! { fn overflowing_rem_int(self, rhs: Self::Bits) -> (Self, bool) }
|
trait_delegate! { fn overflowing_rem_int(self, rhs: Self::Bits) -> (Self, bool) }
|
||||||
|
|
Loading…
Reference in New Issue