// Copyright © 2016–2023 Trevor Spiteri
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option) any
// later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General Public License and
// a copy of the GNU General Public License along with this program. If not, see
// <https://www.gnu.org/licenses/>.
/*!
Operations on numbers.
See the documentation for each trait method to see a usage example.
*/
/**
Compound negation and assignment.
# Examples
```rust
use rug::ops::NegAssign;
struct I(i32);
impl NegAssign for I {
fn neg_assign(&mut self) {
self.0 = -self.0;
}
}
let mut i = I(42);
i.neg_assign();
assert_eq!(i.0, -42);
```
*/
/**
Compound bitwise complement and assignement.
# Examples
```rust
use rug::ops::NotAssign;
struct I(i32);
impl NotAssign for I {
fn not_assign(&mut self) {
self.0 = !self.0;
}
}
let mut i = I(42);
i.not_assign();
assert_eq!(i.0, !42);
```
*/
/**
Compound addition and assignment to the rhs operand.
`rhs.add_from(lhs)` has the same effect as `rhs = lhs + rhs`.
# Examples
```rust
use rug::ops::AddFrom;
struct S(String);
impl AddFrom<&str> for S {
fn add_from(&mut self, lhs: &str) {
self.0.insert_str(0, lhs);
}
}
let mut s = S("world!".into());
s.add_from("Hello, ");
assert_eq!(s.0, "Hello, world!");
```
*/
/**
Compound subtraction and assignment to the rhs operand.
`rhs.sub_from(lhs)` has the same effect as `rhs = lhs - rhs`.
# Examples
```rust
use rug::ops::SubFrom;
struct I(i32);
impl SubFrom<i32> for I {
fn sub_from(&mut self, lhs: i32) {
self.0 = lhs - self.0;
}
}
let mut i = I(10);
i.sub_from(42);
assert_eq!(i.0, 32);
```
*/
/**
Compound multiplication and assignment to the rhs operand.
`rhs.mul_from(lhs)` has the same effect as `rhs = lhs * rhs`.
# Examples
```rust
use rug::ops::MulFrom;
struct ColumnVec(i32, i32);
struct SquareMatrix(ColumnVec, ColumnVec);
impl MulFrom<&SquareMatrix> for ColumnVec {
fn mul_from(&mut self, lhs: &SquareMatrix) {
let SquareMatrix(ref left, ref right) = *lhs;
let out_0 = left.0 * self.0 + right.0 * self.1;
self.1 = left.1 * self.0 + right.1 * self.1;
self.0 = out_0;
}
}
let mut col = ColumnVec(2, 30);
let matrix_left = ColumnVec(1, -2);
let matrix_right = ColumnVec(3, -1);
let matrix = SquareMatrix(matrix_left, matrix_right);
// ( 1 3) ( 2) = ( 92)
// (-2 -1) (30) (-34)
col.mul_from(&matrix);
assert_eq!(col.0, 92);
assert_eq!(col.1, -34);
```
*/
/**
Compound division and assignment to the rhs operand.
`rhs.div_from(lhs)` has the same effect as `rhs = lhs / rhs`.
# Examples
```rust
use rug::ops::DivFrom;
struct I(i32);
impl DivFrom<i32> for I {
fn div_from(&mut self, lhs: i32) {
self.0 = lhs / self.0;
}
}
let mut i = I(10);
i.div_from(42);
assert_eq!(i.0, 4);
```
*/
/**
Compound remainder operation and assignment to the rhs operand.
`rhs.rem_from(lhs)` has the same effect as `rhs = lhs % rhs`.
# Examples
```rust
use rug::ops::RemFrom;
struct I(i32);
impl RemFrom<i32> for I {
fn rem_from(&mut self, lhs: i32) {
self.0 = lhs % self.0;
}
}
let mut i = I(10);
i.rem_from(42);
assert_eq!(i.0, 2);
```
*/
/**
Compound bitwise AND and assignment to the rhs operand.
`rhs.bitand_from(lhs)` has the same effect as `rhs = lhs & rhs`.
# Examples
```rust
use rug::ops::BitAndFrom;
struct U(u32);
impl BitAndFrom<u32> for U {
fn bitand_from(&mut self, lhs: u32) {
self.0 = lhs & self.0;
}
}
let mut u = U(0xff);
u.bitand_from(0xf0);
assert_eq!(u.0, 0xf0);
```
*/
/**
Compound bitwise OR and assignment to the rhs operand.
`rhs.bitor_from(lhs)` has the same effect as `rhs = lhs | rhs`.
# Examples
```rust
use rug::ops::BitOrFrom;
struct U(u32);
impl BitOrFrom<u32> for U {
fn bitor_from(&mut self, lhs: u32) {
self.0 = lhs | self.0;
}
}
let mut u = U(0xf);
u.bitor_from(0xf0);
assert_eq!(u.0, 0xff);
```
*/
/**
Compound bitwise XOR and assignment to the rhs operand.
`rhs.bitxor_from(lhs)` has the same effect as `rhs = lhs ^ rhs`.
# Examples
```rust
use rug::ops::BitXorFrom;
struct U(u32);
impl BitXorFrom<u32> for U {
fn bitxor_from(&mut self, lhs: u32) {
self.0 = lhs ^ self.0;
}
}
let mut u = U(0xf);
u.bitxor_from(0xff);
assert_eq!(u.0, 0xf0);
```
*/
/**
Compound left shift and assignment to the rhs operand.
`rhs.shl_from(lhs)` has the same effect as `rhs = lhs << rhs`.
# Examples
```rust
# #[cfg(feature = "integer")] {
use core::mem;
use rug::ops::ShlFrom;
use rug::Integer;
struct I(Integer);
impl ShlFrom for I {
fn shl_from(&mut self, mut lhs: I) {
let rhs = self.0.to_i32().expect("overflow");
mem::swap(self, &mut lhs);
self.0 <<= rhs;
}
}
let mut i = I(Integer::from(200));
i.shl_from(I(Integer::from(0xf000)));
let expected = Integer::from(0xf000) << 200;
assert_eq!(i.0, expected);
# }
```
*/
/**
Compound right shift and assignment to the rhs operand.
`rhs.shr_from(lhs)` has the same effect as `rhs = lhs >> rhs`.
# Examples
```rust
# #[cfg(feature = "integer")] {
use core::mem;
use rug::ops::ShrFrom;
use rug::Integer;
struct I(Integer);
impl ShrFrom for I {
fn shr_from(&mut self, mut lhs: I) {
let rhs = self.0.to_i32().expect("overflow");
mem::swap(self, &mut lhs);
self.0 >>= rhs;
}
}
let mut i = I(Integer::from(4));
i.shr_from(I(Integer::from(0xf000)));
let expected = Integer::from(0xf000) >> 4;
assert_eq!(i.0, expected);
# }
```
*/
/**
The power operation.
# Examples
```rust
use rug::ops::Pow;
struct U(u32);
impl Pow<u16> for U {
type Output = u32;
fn pow(self, rhs: u16) -> u32 {
self.0.pow(u32::from(rhs))
}
}
let u = U(5);
assert_eq!(u.pow(2_u16), 25);
```
*/
pub use Pow;
/**
Compound power operation and assignment.
# Examples
```rust
use rug::ops::PowAssign;
struct U(u32);
impl PowAssign<u16> for U {
fn pow_assign(&mut self, rhs: u16) {
self.0 = self.0.pow(u32::from(rhs));
}
}
let mut u = U(5);
u.pow_assign(2_u16);
assert_eq!(u.0, 25);
```
*/
/**
Compound power operation and assignment to the rhs operand.
`rhs.pow_from(lhs)` has the same effect as `rhs = lhs.pow(rhs)`.
# Examples
```rust
use rug::ops::PowFrom;
struct U(u32);
impl PowFrom<u32> for U {
fn pow_from(&mut self, lhs: u32) {
self.0 = lhs.pow(self.0);
}
}
let mut u = U(2);
u.pow_from(5);
assert_eq!(u.0, 25);
```
*/
/**
Assignment with a specified rounding method.
# Examples
```rust
# #[cfg(feature = "float")] {
use core::cmp::Ordering;
use rug::float::Round;
use rug::ops::AssignRound;
struct F(f64);
impl AssignRound<f64> for F {
type Round = Round;
type Ordering = Ordering;
fn assign_round(&mut self, rhs: f64, _round: Round) -> Ordering {
self.0 = rhs;
Ordering::Equal
}
}
let mut f = F(3.0);
let dir = f.assign_round(5.0, Round::Nearest);
assert_eq!(f.0, 5.0);
assert_eq!(dir, Ordering::Equal);
# }
```
*/
/**
Completes an [incomplete-computation value][icv] with a specified precision and
rounding method.
# Examples
Implementing the trait:
```rust
# #[cfg(feature = "float")] {
use core::cmp::Ordering;
use rug::float::Round;
use rug::ops::{CompleteRound, Pow};
use rug::Float;
struct LazyPow4<'a>(&'a Float);
impl CompleteRound for LazyPow4<'_> {
type Completed = Float;
type Prec = u32;
type Round = Round;
type Ordering = Ordering;
fn complete_round(self, prec: Self::Prec, round: Self::Round) -> (Float, Ordering) {
Float::with_val_round(prec, self.0.pow(4), round)
}
}
let (val, dir) = LazyPow4(&Float::with_val(53, 3.5)).complete_round(53, Round::Nearest);
assert_eq!(val, 3.5f32.pow(4));
assert_eq!(dir, Ordering::Equal);
# }
```
Completing an [incomplete-computation value][icv]:
```rust
# #[cfg(feature = "float")] {
use core::cmp::Ordering;
use rug::float::Round;
use rug::ops::CompleteRound;
use rug::Float;
let incomplete = Float::u_pow_u(3, 4);
let (complete, dir) = incomplete.complete_round(53, Round::Nearest);
assert_eq!(complete, 81);
assert_eq!(dir, Ordering::Equal);
# }
```
[icv]: crate#incomplete-computation-values
*/
/**
Compound addition and assignment with a specified rounding method.
# Examples
```rust
# #[cfg(feature = "float")] {
use core::cmp::Ordering;
use rug::float::Round;
use rug::ops::AddAssignRound;
use rug::Float;
struct F(f64);
impl AddAssignRound<f64> for F {
type Round = Round;
type Ordering = Ordering;
fn add_assign_round(&mut self, rhs: f64, round: Round) -> Ordering {
let mut f = Float::with_val(53, self.0);
let dir = f.add_assign_round(rhs, round);
self.0 = f.to_f64();
dir
}
}
let mut f = F(3.0);
let dir = f.add_assign_round(5.0, Round::Nearest);
// 3.0 + 5.0 = 8.0
assert_eq!(f.0, 8.0);
assert_eq!(dir, Ordering::Equal);
# }
```
*/
/**
Compound addition and assignment to the rhs operand with a specified rounding
method.
# Examples
```rust
# #[cfg(feature = "float")] {
use core::cmp::Ordering;
use rug::float::Round;
use rug::ops::{AddAssignRound, AddFromRound};
use rug::Float;
struct F(f64);
impl AddFromRound<f64> for F {
type Round = Round;
type Ordering = Ordering;
fn add_from_round(&mut self, lhs: f64, round: Round) -> Ordering {
let mut f = Float::with_val(53, lhs);
let dir = f.add_assign_round(self.0, round);
self.0 = f.to_f64();
dir
}
}
let mut f = F(5.0);
let dir = f.add_from_round(3.0, Round::Nearest);
// 3.0 + 5.0 = 8.0
assert_eq!(f.0, 8.0);
assert_eq!(dir, Ordering::Equal);
# }
```
*/
/**
Compound subtraction and assignment with a specified rounding method.
# Examples
```rust
# #[cfg(feature = "float")] {
use core::cmp::Ordering;
use rug::float::Round;
use rug::ops::SubAssignRound;
use rug::Float;
struct F(f64);
impl SubAssignRound<f64> for F {
type Round = Round;
type Ordering = Ordering;
fn sub_assign_round(&mut self, rhs: f64, round: Round) -> Ordering {
let mut f = Float::with_val(53, self.0);
let dir = f.sub_assign_round(rhs, round);
self.0 = f.to_f64();
dir
}
}
let mut f = F(3.0);
let dir = f.sub_assign_round(5.0, Round::Nearest);
// 3.0 - 5.0 = -2.0
assert_eq!(f.0, -2.0);
assert_eq!(dir, Ordering::Equal);
# }
```
*/
/**
Compound subtraction and assignment to the rhs operand with a specified rounding
method.
# Examples
```rust
# #[cfg(feature = "float")] {
use core::cmp::Ordering;
use rug::float::Round;
use rug::ops::{SubAssignRound, SubFromRound};
use rug::Float;
struct F(f64);
impl SubFromRound<f64> for F {
type Round = Round;
type Ordering = Ordering;
fn sub_from_round(&mut self, lhs: f64, round: Round) -> Ordering {
let mut f = Float::with_val(53, lhs);
let dir = f.sub_assign_round(self.0, round);
self.0 = f.to_f64();
dir
}
}
let mut f = F(5.0);
let dir = f.sub_from_round(3.0, Round::Nearest);
// 3.0 - 5.0 = -2.0
assert_eq!(f.0, -2.0);
assert_eq!(dir, Ordering::Equal);
# }
```
*/
/**
Compound multiplication and assignment with a specified rounding method.
# Examples
```rust
# #[cfg(feature = "float")] {
use core::cmp::Ordering;
use rug::float::Round;
use rug::ops::MulAssignRound;
use rug::Float;
struct F(f64);
impl MulAssignRound<f64> for F {
type Round = Round;
type Ordering = Ordering;
fn mul_assign_round(&mut self, rhs: f64, round: Round) -> Ordering {
let mut f = Float::with_val(53, self.0);
let dir = f.mul_assign_round(rhs, round);
self.0 = f.to_f64();
dir
}
}
let mut f = F(3.0);
let dir = f.mul_assign_round(5.0, Round::Nearest);
// 3.0 × 5.0 = 15.0
assert_eq!(f.0, 15.0);
assert_eq!(dir, Ordering::Equal);
# }
```
*/
/**
Compound multiplication and assignment to the rhs operand with a specified
rounding method.
# Examples
```rust
# #[cfg(feature = "float")] {
use core::cmp::Ordering;
use rug::float::Round;
use rug::ops::{MulAssignRound, MulFromRound};
use rug::Float;
struct F(f64);
impl MulFromRound<f64> for F {
type Round = Round;
type Ordering = Ordering;
fn mul_from_round(&mut self, lhs: f64, round: Round) -> Ordering {
let mut f = Float::with_val(53, lhs);
let dir = f.mul_assign_round(self.0, round);
self.0 = f.to_f64();
dir
}
}
let mut f = F(5.0);
let dir = f.mul_from_round(3.0, Round::Nearest);
// 3.0 × 5.0 = 15.0
assert_eq!(f.0, 15.0);
assert_eq!(dir, Ordering::Equal);
# }
```
*/
/**
Compound division and assignment with a specified rounding method.
# Examples
```rust
# #[cfg(feature = "float")] {
use core::cmp::Ordering;
use rug::float::Round;
use rug::ops::DivAssignRound;
use rug::Float;
struct F(f64);
impl DivAssignRound<f64> for F {
type Round = Round;
type Ordering = Ordering;
fn div_assign_round(&mut self, rhs: f64, round: Round) -> Ordering {
let mut f = Float::with_val(53, self.0);
let dir = f.div_assign_round(rhs, round);
self.0 = f.to_f64();
dir
}
}
let mut f = F(3.0);
let dir = f.div_assign_round(4.0, Round::Nearest);
// 3.0 / 4.0 = 0.75
assert_eq!(f.0, 0.75);
assert_eq!(dir, Ordering::Equal);
# }
```
*/
/**
Compound division and assignment to the rhs operand with a specified rounding
method.
# Examples
```rust
# #[cfg(feature = "float")] {
use core::cmp::Ordering;
use rug::float::Round;
use rug::ops::{DivAssignRound, DivFromRound};
use rug::Float;
struct F(f64);
impl DivFromRound<f64> for F {
type Round = Round;
type Ordering = Ordering;
fn div_from_round(&mut self, lhs: f64, round: Round) -> Ordering {
let mut f = Float::with_val(53, lhs);
let dir = f.div_assign_round(self.0, round);
self.0 = f.to_f64();
dir
}
}
let mut f = F(4.0);
let dir = f.div_from_round(3.0, Round::Nearest);
// 3.0 / 4.0 = 0.75
assert_eq!(f.0, 0.75);
assert_eq!(dir, Ordering::Equal);
# }
```
*/
/**
Compound remainder operation and assignment with a specified rounding method.
# Examples
```rust
# #[cfg(feature = "float")] {
use core::cmp::Ordering;
use rug::float::Round;
use rug::ops::RemAssignRound;
use rug::Float;
struct F(f64);
impl RemAssignRound<f64> for F {
type Round = Round;
type Ordering = Ordering;
fn rem_assign_round(&mut self, rhs: f64, round: Round) -> Ordering {
let mut f = Float::with_val(53, self.0);
let dir = f.rem_assign_round(rhs, round);
self.0 = f.to_f64();
dir
}
}
let mut f = F(3.25);
let dir = f.rem_assign_round(1.25, Round::Nearest);
// 3.25 % 1.25 = 0.75
assert_eq!(f.0, 0.75);
assert_eq!(dir, Ordering::Equal);
# }
```
*/
/**
Compound remainder operation and assignment to the rhs operand with a specified
rounding method.
# Examples
```rust
# #[cfg(feature = "float")] {
use core::cmp::Ordering;
use rug::float::Round;
use rug::ops::{RemAssignRound, RemFromRound};
use rug::Float;
struct F(f64);
impl RemFromRound<f64> for F {
type Round = Round;
type Ordering = Ordering;
fn rem_from_round(&mut self, lhs: f64, round: Round) -> Ordering {
let mut f = Float::with_val(53, lhs);
let dir = f.rem_assign_round(self.0, round);
self.0 = f.to_f64();
dir
}
}
let mut f = F(1.25);
let dir = f.rem_from_round(3.25, Round::Nearest);
// 3.25 % 1.25 = 0.75
assert_eq!(f.0, 0.75);
assert_eq!(dir, Ordering::Equal);
# }
```
*/
/**
Compound power operation and assignment with a specified rounding method.
# Examples
```rust
# #[cfg(feature = "float")] {
use core::cmp::Ordering;
use rug::float::Round;
use rug::ops::PowAssignRound;
use rug::Float;
struct F(f64);
impl PowAssignRound<f64> for F {
type Round = Round;
type Ordering = Ordering;
fn pow_assign_round(&mut self, rhs: f64, round: Round) -> Ordering {
let mut f = Float::with_val(53, self.0);
let dir = f.pow_assign_round(rhs, round);
self.0 = f.to_f64();
dir
}
}
let mut f = F(3.0);
let dir = f.pow_assign_round(5.0, Round::Nearest);
// 3.0 ^ 5.0 = 243.0
assert_eq!(f.0, 243.0);
assert_eq!(dir, Ordering::Equal);
# }
```
*/
/**
Compound power operation and assignment to the rhs operand with a specified
rounding method.
# Examples
```rust
# #[cfg(feature = "float")] {
use core::cmp::Ordering;
use rug::float::Round;
use rug::ops::{PowAssignRound, PowFromRound};
use rug::Float;
struct F(f64);
impl PowFromRound<f64> for F {
type Round = Round;
type Ordering = Ordering;
fn pow_from_round(&mut self, lhs: f64, round: Round) -> Ordering {
let mut f = Float::with_val(53, lhs);
let dir = f.pow_assign_round(self.0, round);
self.0 = f.to_f64();
dir
}
}
let mut f = F(5.0);
let dir = f.pow_from_round(3.0, Round::Nearest);
// 3.0 ^ 5.0 = 243.0
assert_eq!(f.0, 243.0);
assert_eq!(dir, Ordering::Equal);
# }
```
*/
/**
Rounding variants of division.
# Examples
```rust
use rug::ops::DivRounding;
struct I(i32);
impl DivRounding<i32> for I {
type Output = i32;
fn div_trunc(self, rhs: i32) -> i32 {
self.0 / rhs
}
fn div_ceil(self, rhs: i32) -> i32 {
let (q, r) = (self.0 / rhs, self.0 % rhs);
let change = if rhs > 0 { r > 0 } else { r < 0 };
if change {
q + 1
} else {
q
}
}
fn div_floor(self, rhs: i32) -> i32 {
let (q, r) = (self.0 / rhs, self.0 % rhs);
let change = if rhs > 0 { r < 0 } else { r > 0 };
if change {
q - 1
} else {
q
}
}
fn div_euc(self, rhs: i32) -> i32 {
let (q, r) = (self.0 / rhs, self.0 % rhs);
if r < 0 {
if rhs < 0 {
q + 1
} else {
q - 1
}
} else {
q
}
}
}
assert_eq!(I(-10).div_trunc(-3), 3);
assert_eq!(I(-10).div_ceil(-3), 4);
assert_eq!(I(-10).div_floor(-3), 3);
assert_eq!(I(-10).div_euc(-3), 4);
```
*/
/**
Compound assignment and rounding variants of division.
# Examples
```rust
use rug::ops::DivRoundingAssign;
struct I(i32);
impl DivRoundingAssign<i32> for I {
fn div_trunc_assign(&mut self, rhs: i32) {
self.0 /= rhs;
}
fn div_ceil_assign(&mut self, rhs: i32) {
let (q, r) = (self.0 / rhs, self.0 % rhs);
let change = if rhs > 0 { r > 0 } else { r < 0 };
self.0 = if change { q + 1 } else { q };
}
fn div_floor_assign(&mut self, rhs: i32) {
let (q, r) = (self.0 / rhs, self.0 % rhs);
let change = if rhs > 0 { r < 0 } else { r > 0 };
self.0 = if change { q - 1 } else { q };
}
fn div_euc_assign(&mut self, rhs: i32) {
let (q, r) = (self.0 / rhs, self.0 % rhs);
self.0 = if r < 0 {
if rhs < 0 {
q + 1
} else {
q - 1
}
} else {
q
};
}
}
let mut div_floor = I(-10);
div_floor.div_floor_assign(3);
assert_eq!(div_floor.0, -4);
```
*/
/**
Compound assignment to the rhs operand and rounding variants of division.
# Examples
```rust
use rug::ops::DivRoundingFrom;
struct I(i32);
impl DivRoundingFrom<i32> for I {
fn div_trunc_from(&mut self, lhs: i32) {
self.0 = lhs / self.0;
}
fn div_ceil_from(&mut self, lhs: i32) {
let (q, r) = (lhs / self.0, lhs % self.0);
let change = if self.0 > 0 { r > 0 } else { r < 0 };
self.0 = if change { q + 1 } else { q };
}
fn div_floor_from(&mut self, lhs: i32) {
let (q, r) = (lhs / self.0, lhs % self.0);
let change = if self.0 > 0 { r < 0 } else { r > 0 };
self.0 = if change { q - 1 } else { q };
}
fn div_euc_from(&mut self, lhs: i32) {
let (q, r) = (lhs / self.0, lhs % self.0);
self.0 = if r < 0 {
if self.0 < 0 {
q + 1
} else {
q - 1
}
} else {
q
};
}
}
let mut div_ceil = I(3);
div_ceil.div_ceil_from(10);
assert_eq!(div_ceil.0, 4);
```
*/
/**
Rounding variants of the remainder operation.
# Examples
```rust
use rug::ops::RemRounding;
struct I(i32);
impl RemRounding<i32> for I {
type Output = i32;
fn rem_trunc(self, rhs: i32) -> i32 {
self.0 % rhs
}
fn rem_ceil(self, rhs: i32) -> i32 {
let r = self.0 % rhs;
let change = if rhs > 0 { r > 0 } else { r < 0 };
if change {
r - rhs
} else {
r
}
}
fn rem_floor(self, rhs: i32) -> i32 {
let r = self.0 % rhs;
let change = if rhs > 0 { r < 0 } else { r > 0 };
if change {
r + rhs
} else {
r
}
}
fn rem_euc(self, rhs: i32) -> i32 {
let r = self.0 % rhs;
if r < 0 {
if rhs < 0 {
r - rhs
} else {
r + rhs
}
} else {
r
}
}
}
assert_eq!(I(-10).rem_trunc(-3), -1);
assert_eq!(I(-10).rem_ceil(-3), 2);
assert_eq!(I(-10).rem_floor(-3), -1);
assert_eq!(I(-10).rem_euc(-3), 2);
```
*/
/**
Compound assignment and rounding variants of the remainder operation.
# Examples
```rust
use rug::ops::RemRoundingAssign;
struct I(i32);
impl RemRoundingAssign<i32> for I {
fn rem_trunc_assign(&mut self, rhs: i32) {
self.0 %= rhs;
}
fn rem_ceil_assign(&mut self, rhs: i32) {
let r = self.0 % rhs;
let change = if rhs > 0 { r > 0 } else { r < 0 };
self.0 = if change { r - rhs } else { r };
}
fn rem_floor_assign(&mut self, rhs: i32) {
let r = self.0 % rhs;
let change = if rhs > 0 { r < 0 } else { r > 0 };
self.0 = if change { r + rhs } else { r };
}
fn rem_euc_assign(&mut self, rhs: i32) {
let r = self.0 % rhs;
self.0 = if r < 0 {
if rhs < 0 {
r - rhs
} else {
r + rhs
}
} else {
r
};
}
}
let mut rem_floor = I(-10);
rem_floor.rem_floor_assign(3);
assert_eq!(rem_floor.0, 2);
```
*/
/**
Compound assignment to the rhs operand and rounding variants of the remainder
operation.
# Examples
```rust
use rug::ops::RemRoundingFrom;
struct I(i32);
impl RemRoundingFrom<i32> for I {
fn rem_trunc_from(&mut self, lhs: i32) {
self.0 = lhs % self.0;
}
fn rem_ceil_from(&mut self, lhs: i32) {
let r = lhs % self.0;
let change = if self.0 > 0 { r > 0 } else { r < 0 };
self.0 = if change { r - self.0 } else { r };
}
fn rem_floor_from(&mut self, lhs: i32) {
let r = lhs % self.0;
let change = if self.0 > 0 { r < 0 } else { r > 0 };
self.0 = if change { r + self.0 } else { r };
}
fn rem_euc_from(&mut self, lhs: i32) {
let r = lhs % self.0;
self.0 = if r < 0 {
if self.0 < 0 {
r - self.0
} else {
r + self.0
}
} else {
r
};
}
}
let mut rem_ceil = I(3);
rem_ceil.rem_ceil_from(10);
assert_eq!(rem_ceil.0, -2);
```
*/