Skip to main content

rug/
ops.rs

1// Copyright © 2016–2026 Trevor Spiteri
2
3// This program is free software: you can redistribute it and/or modify it under
4// the terms of the GNU Lesser General Public License as published by the Free
5// Software Foundation, either version 3 of the License, or (at your option) any
6// later version.
7//
8// This program is distributed in the hope that it will be useful, but WITHOUT
9// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11// details.
12//
13// You should have received a copy of the GNU Lesser General Public License and
14// a copy of the GNU General Public License along with this program. If not, see
15// <https://www.gnu.org/licenses/>.
16
17/*!
18Operations on numbers.
19
20See the documentation for each trait method to see a usage example.
21*/
22
23/**
24Compound negation and assignment.
25
26# Examples
27
28```rust
29use rug::ops::NegAssign;
30struct I(i32);
31impl NegAssign for I {
32    fn neg_assign(&mut self) {
33        self.0 = -self.0;
34    }
35}
36let mut i = I(42);
37i.neg_assign();
38assert_eq!(i.0, -42);
39```
40*/
41pub trait NegAssign {
42    /// Peforms the negation.
43    ///
44    /// # Examples
45    ///
46    /// ```rust
47    /// # #[cfg(feature = "integer")] {
48    /// use rug::ops::NegAssign;
49    /// use rug::Integer;
50    /// let mut i = Integer::from(-42);
51    /// i.neg_assign();
52    /// assert_eq!(i, 42);
53    /// # }
54    /// ```
55    fn neg_assign(&mut self);
56}
57
58/**
59Compound bitwise complement and assignement.
60
61# Examples
62
63```rust
64use rug::ops::NotAssign;
65struct I(i32);
66impl NotAssign for I {
67    fn not_assign(&mut self) {
68        self.0 = !self.0;
69    }
70}
71let mut i = I(42);
72i.not_assign();
73assert_eq!(i.0, !42);
74```
75*/
76pub trait NotAssign {
77    /// Peforms the complement.
78    ///
79    /// # Examples
80    ///
81    /// ```rust
82    /// # #[cfg(feature = "integer")] {
83    /// use rug::ops::NotAssign;
84    /// use rug::Integer;
85    /// let mut i = Integer::from(-42);
86    /// i.not_assign();
87    /// assert_eq!(i, !-42);
88    /// # }
89    /// ```
90    fn not_assign(&mut self);
91}
92
93/**
94Compound addition and assignment to the rhs operand.
95
96`rhs.add_from(lhs)` has the same effect as `rhs = lhs + rhs`.
97
98# Examples
99
100```rust
101use rug::ops::AddFrom;
102struct S(String);
103impl AddFrom<&str> for S {
104    fn add_from(&mut self, lhs: &str) {
105        self.0.insert_str(0, lhs);
106    }
107}
108let mut s = S("world!".into());
109s.add_from("Hello, ");
110assert_eq!(s.0, "Hello, world!");
111```
112*/
113pub trait AddFrom<Lhs = Self> {
114    /// Peforms the addition.
115    ///
116    /// # Examples
117    ///
118    /// ```rust
119    /// # #[cfg(feature = "integer")] {
120    /// use rug::ops::AddFrom;
121    /// use rug::Integer;
122    /// let mut rhs = Integer::from(10);
123    /// rhs.add_from(100);
124    /// // rhs = 100 + 10
125    /// assert_eq!(rhs, 110);
126    /// # }
127    /// ```
128    fn add_from(&mut self, lhs: Lhs);
129}
130
131/**
132Compound subtraction and assignment to the rhs operand.
133
134`rhs.sub_from(lhs)` has the same effect as `rhs = lhs - rhs`.
135
136# Examples
137
138```rust
139use rug::ops::SubFrom;
140struct I(i32);
141impl SubFrom<i32> for I {
142    fn sub_from(&mut self, lhs: i32) {
143        self.0 = lhs - self.0;
144    }
145}
146let mut i = I(10);
147i.sub_from(42);
148assert_eq!(i.0, 32);
149```
150*/
151pub trait SubFrom<Lhs = Self> {
152    /// Peforms the subtraction.
153    ///
154    /// # Examples
155    ///
156    /// ```rust
157    /// # #[cfg(feature = "integer")] {
158    /// use rug::ops::SubFrom;
159    /// use rug::Integer;
160    /// let mut rhs = Integer::from(10);
161    /// rhs.sub_from(100);
162    /// // rhs = 100 - 10
163    /// assert_eq!(rhs, 90);
164    /// # }
165    /// ```
166    fn sub_from(&mut self, lhs: Lhs);
167}
168
169/**
170Compound multiplication and assignment to the rhs operand.
171
172`rhs.mul_from(lhs)` has the same effect as `rhs = lhs * rhs`.
173
174# Examples
175
176```rust
177use rug::ops::MulFrom;
178struct ColumnVec(i32, i32);
179struct SquareMatrix(ColumnVec, ColumnVec);
180impl MulFrom<&SquareMatrix> for ColumnVec {
181    fn mul_from(&mut self, lhs: &SquareMatrix) {
182        let SquareMatrix(ref left, ref right) = *lhs;
183        let out_0 = left.0 * self.0 + right.0 * self.1;
184        self.1 = left.1 * self.0 + right.1 * self.1;
185        self.0 = out_0;
186    }
187}
188let mut col = ColumnVec(2, 30);
189let matrix_left = ColumnVec(1, -2);
190let matrix_right = ColumnVec(3, -1);
191let matrix = SquareMatrix(matrix_left, matrix_right);
192// ( 1   3) ( 2) = ( 92)
193// (-2  -1) (30)   (-34)
194col.mul_from(&matrix);
195assert_eq!(col.0, 92);
196assert_eq!(col.1, -34);
197```
198*/
199pub trait MulFrom<Lhs = Self> {
200    /// Peforms the multiplication.
201    ///
202    /// # Examples
203    ///
204    /// ```rust
205    /// # #[cfg(feature = "integer")] {
206    /// use rug::ops::MulFrom;
207    /// use rug::Integer;
208    /// let mut rhs = Integer::from(5);
209    /// rhs.mul_from(50);
210    /// // rhs = 50 × 5
211    /// assert_eq!(rhs, 250);
212    /// # }
213    /// ```
214    fn mul_from(&mut self, lhs: Lhs);
215}
216
217/**
218Compound division and assignment to the rhs operand.
219
220`rhs.div_from(lhs)` has the same effect as `rhs = lhs / rhs`.
221
222# Examples
223
224```rust
225use rug::ops::DivFrom;
226struct I(i32);
227impl DivFrom<i32> for I {
228    fn div_from(&mut self, lhs: i32) {
229        self.0 = lhs / self.0;
230    }
231}
232let mut i = I(10);
233i.div_from(42);
234assert_eq!(i.0, 4);
235```
236*/
237pub trait DivFrom<Lhs = Self> {
238    /// Peforms the division.
239    ///
240    /// # Examples
241    ///
242    /// ```rust
243    /// # #[cfg(feature = "integer")] {
244    /// use rug::ops::DivFrom;
245    /// use rug::Integer;
246    /// let mut rhs = Integer::from(5);
247    /// rhs.div_from(50);
248    /// // rhs = 50 / 5
249    /// assert_eq!(rhs, 10);
250    /// # }
251    /// ```
252    fn div_from(&mut self, lhs: Lhs);
253}
254
255/**
256Compound remainder operation and assignment to the rhs operand.
257
258`rhs.rem_from(lhs)` has the same effect as `rhs = lhs % rhs`.
259
260# Examples
261
262```rust
263use rug::ops::RemFrom;
264struct I(i32);
265impl RemFrom<i32> for I {
266    fn rem_from(&mut self, lhs: i32) {
267        self.0 = lhs % self.0;
268    }
269}
270let mut i = I(10);
271i.rem_from(42);
272assert_eq!(i.0, 2);
273```
274*/
275pub trait RemFrom<Lhs = Self> {
276    /// Peforms the remainder operation.
277    ///
278    /// # Examples
279    ///
280    /// ```rust
281    /// # #[cfg(feature = "integer")] {
282    /// use rug::ops::RemFrom;
283    /// use rug::Integer;
284    /// let mut rhs = Integer::from(2);
285    /// rhs.rem_from(17);
286    /// // rhs = 17 / 2
287    /// assert_eq!(rhs, 1);
288    /// # }
289    /// ```
290    fn rem_from(&mut self, lhs: Lhs);
291}
292
293/**
294Compound bitwise AND and assignment to the rhs operand.
295
296`rhs.bitand_from(lhs)` has the same effect as `rhs = lhs & rhs`.
297
298# Examples
299
300```rust
301use rug::ops::BitAndFrom;
302struct U(u32);
303impl BitAndFrom<u32> for U {
304    fn bitand_from(&mut self, lhs: u32) {
305        self.0 = lhs & self.0;
306    }
307}
308let mut u = U(0xff);
309u.bitand_from(0xf0);
310assert_eq!(u.0, 0xf0);
311```
312*/
313pub trait BitAndFrom<Lhs = Self> {
314    /// Peforms the AND operation.
315    ///
316    /// # Examples
317    ///
318    /// ```rust
319    /// # #[cfg(feature = "integer")] {
320    /// use rug::ops::BitAndFrom;
321    /// use rug::Integer;
322    /// let mut rhs = Integer::from(0xf0);
323    /// rhs.bitand_from(0x33);
324    /// // rhs = 0x33 & 0xf0
325    /// assert_eq!(rhs, 0x30);
326    /// # }
327    /// ```
328    fn bitand_from(&mut self, lhs: Lhs);
329}
330
331/**
332Compound bitwise OR and assignment to the rhs operand.
333
334`rhs.bitor_from(lhs)` has the same effect as `rhs = lhs | rhs`.
335
336# Examples
337
338```rust
339use rug::ops::BitOrFrom;
340struct U(u32);
341impl BitOrFrom<u32> for U {
342    fn bitor_from(&mut self, lhs: u32) {
343        self.0 = lhs | self.0;
344    }
345}
346let mut u = U(0xf);
347u.bitor_from(0xf0);
348assert_eq!(u.0, 0xff);
349```
350*/
351pub trait BitOrFrom<Lhs = Self> {
352    /// Peforms the OR operation.
353    ///
354    /// # Examples
355    ///
356    /// ```rust
357    /// # #[cfg(feature = "integer")] {
358    /// use rug::ops::BitOrFrom;
359    /// use rug::Integer;
360    /// let mut rhs = Integer::from(0xf0);
361    /// rhs.bitor_from(0x33);
362    /// // rhs = 0x33 | 0xf0
363    /// assert_eq!(rhs, 0xf3);
364    /// # }
365    /// ```
366    fn bitor_from(&mut self, lhs: Lhs);
367}
368
369/**
370Compound bitwise XOR and assignment to the rhs operand.
371
372`rhs.bitxor_from(lhs)` has the same effect as `rhs = lhs ^ rhs`.
373
374# Examples
375
376```rust
377use rug::ops::BitXorFrom;
378struct U(u32);
379impl BitXorFrom<u32> for U {
380    fn bitxor_from(&mut self, lhs: u32) {
381        self.0 = lhs ^ self.0;
382    }
383}
384let mut u = U(0xf);
385u.bitxor_from(0xff);
386assert_eq!(u.0, 0xf0);
387```
388*/
389pub trait BitXorFrom<Lhs = Self> {
390    /// Peforms the XOR operation.
391    ///
392    /// # Examples
393    ///
394    /// ```rust
395    /// # #[cfg(feature = "integer")] {
396    /// use rug::ops::BitXorFrom;
397    /// use rug::Integer;
398    /// let mut rhs = Integer::from(0xf0);
399    /// rhs.bitxor_from(0x33);
400    /// // rhs = 0x33 ^ 0xf0
401    /// assert_eq!(rhs, 0xc3);
402    /// # }
403    /// ```
404    fn bitxor_from(&mut self, lhs: Lhs);
405}
406
407/**
408Compound left shift and assignment to the rhs operand.
409
410`rhs.shl_from(lhs)` has the same effect as `rhs = lhs << rhs`.
411
412# Examples
413
414```rust
415# #[cfg(feature = "integer")] {
416use core::mem;
417use rug::ops::ShlFrom;
418use rug::Integer;
419struct I(Integer);
420impl ShlFrom for I {
421    fn shl_from(&mut self, mut lhs: I) {
422        let rhs = self.0.to_i32().expect("overflow");
423        mem::swap(self, &mut lhs);
424        self.0 <<= rhs;
425    }
426}
427let mut i = I(Integer::from(200));
428i.shl_from(I(Integer::from(0xf000)));
429let expected = Integer::from(0xf000) << 200;
430assert_eq!(i.0, expected);
431# }
432```
433*/
434pub trait ShlFrom<Lhs = Self> {
435    /// Peforms the left shift.
436    ///
437    /// # Examples
438    ///
439    /// ```rust
440    /// use rug::ops::ShlFrom;
441    /// let mut rhs = 4;
442    /// rhs.shl_from(0x00f0);
443    /// // rhs = 0x00f0 << 4
444    /// assert_eq!(rhs, 0x0f00);
445    /// ```
446    fn shl_from(&mut self, lhs: Lhs);
447}
448
449/**
450Compound right shift and assignment to the rhs operand.
451
452`rhs.shr_from(lhs)` has the same effect as `rhs = lhs >> rhs`.
453
454# Examples
455
456```rust
457# #[cfg(feature = "integer")] {
458use core::mem;
459use rug::ops::ShrFrom;
460use rug::Integer;
461struct I(Integer);
462impl ShrFrom for I {
463    fn shr_from(&mut self, mut lhs: I) {
464        let rhs = self.0.to_i32().expect("overflow");
465        mem::swap(self, &mut lhs);
466        self.0 >>= rhs;
467    }
468}
469let mut i = I(Integer::from(4));
470i.shr_from(I(Integer::from(0xf000)));
471let expected = Integer::from(0xf000) >> 4;
472assert_eq!(i.0, expected);
473# }
474```
475*/
476pub trait ShrFrom<Lhs = Self> {
477    /// Peforms the right shift.
478    ///
479    /// # Examples
480    ///
481    /// ```rust
482    /// use rug::ops::ShrFrom;
483    /// let mut rhs = 4;
484    /// rhs.shr_from(0x00f0);
485    /// // rhs = 0x00f0 >> 4
486    /// assert_eq!(rhs, 0x000f);
487    /// ```
488    fn shr_from(&mut self, lhs: Lhs);
489}
490
491#[cfg(not(feature = "num-traits"))]
492/**
493The power operation.
494
495# Examples
496
497```rust
498use rug::ops::Pow;
499struct U(u32);
500impl Pow<u16> for U {
501    type Output = u32;
502    fn pow(self, rhs: u16) -> u32 {
503        self.0.pow(u32::from(rhs))
504    }
505}
506let u = U(5);
507assert_eq!(u.pow(2_u16), 25);
508```
509*/
510pub trait Pow<Rhs> {
511    /// The resulting type after the power operation.
512    type Output;
513    /// Performs the power operation.
514    ///
515    /// # Examples
516    ///
517    /// ```rust
518    /// # #[cfg(feature = "integer")] {
519    /// use rug::ops::Pow;
520    /// use rug::Integer;
521    /// let base = Integer::from(10);
522    /// let power = base.pow(5);
523    /// assert_eq!(power, 100_000);
524    /// # }
525    /// ```
526    fn pow(self, rhs: Rhs) -> Self::Output;
527}
528
529#[cfg(feature = "num-traits")]
530#[doc(inline)]
531pub use num_traits::pow::Pow;
532
533/**
534Compound power operation and assignment.
535
536# Examples
537
538```rust
539use rug::ops::PowAssign;
540struct U(u32);
541impl PowAssign<u16> for U {
542    fn pow_assign(&mut self, rhs: u16) {
543        self.0 = self.0.pow(u32::from(rhs));
544    }
545}
546let mut u = U(5);
547u.pow_assign(2_u16);
548assert_eq!(u.0, 25);
549```
550*/
551pub trait PowAssign<Rhs> {
552    /// Peforms the power operation.
553    ///
554    /// # Examples
555    ///
556    /// ```rust
557    /// # #[cfg(feature = "integer")] {
558    /// use rug::ops::PowAssign;
559    /// use rug::Integer;
560    /// let mut i = Integer::from(10);
561    /// i.pow_assign(5);
562    /// assert_eq!(i, 100_000);
563    /// # }
564    /// ```
565    fn pow_assign(&mut self, rhs: Rhs);
566}
567
568/**
569Compound power operation and assignment to the rhs operand.
570
571`rhs.pow_from(lhs)` has the same effect as `rhs = lhs.pow(rhs)`.
572
573# Examples
574
575```rust
576use rug::ops::PowFrom;
577struct U(u32);
578impl PowFrom<u32> for U {
579    fn pow_from(&mut self, lhs: u32) {
580        self.0 = lhs.pow(self.0);
581    }
582}
583let mut u = U(2);
584u.pow_from(5);
585assert_eq!(u.0, 25);
586```
587*/
588pub trait PowFrom<Lhs = Self> {
589    /// Peforms the power operation.
590    ///
591    /// # Examples
592    ///
593    /// ```rust
594    /// # #[cfg(feature = "float")] {
595    /// use rug::ops::PowFrom;
596    /// use rug::Float;
597    /// let mut rhs = Float::with_val(53, 5);
598    /// rhs.pow_from(10);
599    /// // rhs = 10 ^ 5
600    /// assert_eq!(rhs, 100_000);
601    /// # }
602    /// ```
603    fn pow_from(&mut self, lhs: Lhs);
604}
605
606/**
607Assignment with a specified rounding method.
608
609# Examples
610
611```rust
612# #[cfg(feature = "float")] {
613use core::cmp::Ordering;
614use rug::float::Round;
615use rug::ops::AssignRound;
616struct F(f64);
617impl AssignRound<f64> for F {
618    type Round = Round;
619    type Ordering = Ordering;
620    fn assign_round(&mut self, rhs: f64, _round: Round) -> Ordering {
621        self.0 = rhs;
622        Ordering::Equal
623    }
624}
625let mut f = F(3.0);
626let dir = f.assign_round(5.0, Round::Nearest);
627assert_eq!(f.0, 5.0);
628assert_eq!(dir, Ordering::Equal);
629# }
630```
631*/
632pub trait AssignRound<Src = Self> {
633    /// The rounding method.
634    type Round;
635    /// The direction from rounding.
636    type Ordering;
637    /// Peforms the assignment.
638    ///
639    /// # Examples
640    ///
641    /// ```rust
642    /// # #[cfg(feature = "float")] {
643    /// use core::cmp::Ordering;
644    /// use rug::float::Round;
645    /// use rug::ops::AssignRound;
646    /// use rug::Float;
647    /// // only four significant bits
648    /// let mut f = Float::new(4);
649    /// let dir = f.assign_round(3.3, Round::Nearest);
650    /// // 3.3 rounded down to 3.25
651    /// assert_eq!(f, 3.25);
652    /// assert_eq!(dir, Ordering::Less);
653    /// let dir = f.assign_round(3.3, Round::Up);
654    /// // 3.3 rounded up to 3.5
655    /// assert_eq!(f, 3.5);
656    /// assert_eq!(dir, Ordering::Greater);
657    /// # }
658    /// ```
659    fn assign_round(&mut self, src: Src, round: Self::Round) -> Self::Ordering;
660}
661
662/**
663Completes an [incomplete-computation value][icv] with a specified precision and
664rounding method.
665
666# Examples
667
668Implementing the trait:
669
670```rust
671# #[cfg(feature = "float")] {
672use core::cmp::Ordering;
673use rug::float::Round;
674use rug::ops::{CompleteRound, Pow};
675use rug::Float;
676struct LazyPow4<'a>(&'a Float);
677impl CompleteRound for LazyPow4<'_> {
678    type Completed = Float;
679    type Prec = u32;
680    type Round = Round;
681    type Ordering = Ordering;
682    fn complete_round(self, prec: Self::Prec, round: Self::Round) -> (Float, Ordering) {
683        Float::with_val_round(prec, self.0.pow(4), round)
684    }
685}
686
687let (val, dir) = LazyPow4(&Float::with_val(53, 3.5)).complete_round(53, Round::Nearest);
688assert_eq!(val, 3.5f32.pow(4));
689assert_eq!(dir, Ordering::Equal);
690# }
691```
692
693Completing an [incomplete-computation value][icv]:
694
695```rust
696# #[cfg(feature = "float")] {
697use core::cmp::Ordering;
698use rug::float::Round;
699use rug::ops::CompleteRound;
700use rug::Float;
701let incomplete = Float::u_pow_u(3, 4);
702let (complete, dir) = incomplete.complete_round(53, Round::Nearest);
703assert_eq!(complete, 81);
704assert_eq!(dir, Ordering::Equal);
705# }
706```
707
708[icv]: crate#incomplete-computation-values
709*/
710pub trait CompleteRound {
711    /// The type of the completed operation.
712    type Completed;
713
714    /// The precision.
715    type Prec;
716
717    /// The rounding method.
718    type Round;
719
720    /// The direction from rounding.
721    type Ordering;
722
723    /// Completes the operation with the specified precision and rounding
724    /// method.
725    fn complete_round(
726        self,
727        prec: Self::Prec,
728        round: Self::Round,
729    ) -> (Self::Completed, Self::Ordering);
730
731    /// Completes the operation with the specified precision and with default
732    /// rounding.
733    ///
734    /// # Examples
735    ///
736    /// ```rust
737    /// # #[cfg(feature = "float")] {
738    /// use rug::ops::CompleteRound;
739    /// use rug::Float;
740    /// let incomplete = Float::u_pow_u(3, 4);
741    /// let complete = incomplete.complete(53);
742    /// assert_eq!(complete, 81);
743    /// # }
744    /// ```
745    #[inline]
746    fn complete(self, prec: Self::Prec) -> Self::Completed
747    where
748        Self: Sized,
749        Self::Round: Default,
750    {
751        self.complete_round(prec, Self::Round::default()).0
752    }
753
754    /// Completes the operation and stores the result in a target with the
755    /// specified rounding method.
756    ///
757    /// # Examples
758    ///
759    /// ```rust
760    /// # #[cfg(feature = "float")] {
761    /// use core::cmp::Ordering;
762    /// use rug::float::Round;
763    /// use rug::ops::CompleteRound;
764    /// use rug::Float;
765    /// let mut complete = Float::new(53);
766    /// let dir = Float::u_pow_u(3, 4).complete_round_into(&mut complete, Round::Nearest);
767    /// assert_eq!(complete, 81);
768    /// assert_eq!(dir, Ordering::Equal);
769    /// # }
770    /// ```
771    #[inline]
772    fn complete_round_into<T>(self, target: &mut T, round: Self::Round) -> Self::Ordering
773    where
774        Self: Sized,
775        T: AssignRound<Self, Round = Self::Round, Ordering = Self::Ordering>,
776    {
777        target.assign_round(self, round)
778    }
779
780    /// Completes the operation and stores the result in a target with default
781    /// rounding.
782    ///
783    /// # Examples
784    ///
785    /// ```rust
786    /// # #[cfg(feature = "float")] {
787    /// use rug::ops::CompleteRound;
788    /// use rug::Float;
789    /// let mut complete = Float::new(53);
790    /// Float::u_pow_u(3, 4).complete_into(&mut complete);
791    /// assert_eq!(complete, 81);
792    /// # }
793    /// ```
794    #[inline]
795    fn complete_into<T>(self, target: &mut T)
796    where
797        Self: Sized,
798        Self::Round: Default,
799        T: AssignRound<Self, Round = Self::Round, Ordering = Self::Ordering>,
800    {
801        self.complete_round_into(target, Self::Round::default());
802    }
803}
804
805/**
806Compound addition and assignment with a specified rounding method.
807
808# Examples
809
810```rust
811# #[cfg(feature = "float")] {
812use core::cmp::Ordering;
813use rug::float::Round;
814use rug::ops::AddAssignRound;
815use rug::Float;
816struct F(f64);
817impl AddAssignRound<f64> for F {
818    type Round = Round;
819    type Ordering = Ordering;
820    fn add_assign_round(&mut self, rhs: f64, round: Round) -> Ordering {
821        let mut f = Float::with_val(53, self.0);
822        let dir = f.add_assign_round(rhs, round);
823        self.0 = f.to_f64();
824        dir
825    }
826}
827let mut f = F(3.0);
828let dir = f.add_assign_round(5.0, Round::Nearest);
829// 3.0 + 5.0 = 8.0
830assert_eq!(f.0, 8.0);
831assert_eq!(dir, Ordering::Equal);
832# }
833```
834*/
835pub trait AddAssignRound<Rhs = Self> {
836    /// The rounding method.
837    type Round;
838    /// The direction from rounding.
839    type Ordering;
840    /// Performs the addition.
841    ///
842    /// # Examples
843    ///
844    /// ```rust
845    /// # #[cfg(feature = "float")] {
846    /// use core::cmp::Ordering;
847    /// use rug::float::Round;
848    /// use rug::ops::AddAssignRound;
849    /// use rug::Float;
850    /// // only four significant bits
851    /// let mut f = Float::with_val(4, -3);
852    /// let dir = f.add_assign_round(-0.3, Round::Nearest);
853    /// // -3.3 rounded up to -3.25
854    /// assert_eq!(f, -3.25);
855    /// assert_eq!(dir, Ordering::Greater);
856    /// # }
857    /// ```
858    fn add_assign_round(&mut self, rhs: Rhs, round: Self::Round) -> Self::Ordering;
859}
860
861/**
862Compound addition and assignment to the rhs operand with a specified rounding
863method.
864
865# Examples
866
867```rust
868# #[cfg(feature = "float")] {
869use core::cmp::Ordering;
870use rug::float::Round;
871use rug::ops::{AddAssignRound, AddFromRound};
872use rug::Float;
873struct F(f64);
874impl AddFromRound<f64> for F {
875    type Round = Round;
876    type Ordering = Ordering;
877    fn add_from_round(&mut self, lhs: f64, round: Round) -> Ordering {
878        let mut f = Float::with_val(53, lhs);
879        let dir = f.add_assign_round(self.0, round);
880        self.0 = f.to_f64();
881        dir
882    }
883}
884let mut f = F(5.0);
885let dir = f.add_from_round(3.0, Round::Nearest);
886// 3.0 + 5.0 = 8.0
887assert_eq!(f.0, 8.0);
888assert_eq!(dir, Ordering::Equal);
889# }
890```
891*/
892pub trait AddFromRound<Lhs = Self> {
893    /// The rounding method.
894    type Round;
895    /// The direction from rounding.
896    type Ordering;
897    /// Performs the addition.
898    ///
899    /// # Examples
900    ///
901    /// ```rust
902    /// # #[cfg(feature = "float")] {
903    /// use core::cmp::Ordering;
904    /// use rug::float::Round;
905    /// use rug::ops::AddFromRound;
906    /// use rug::Float;
907    /// // only four significant bits
908    /// let mut f = Float::with_val(4, -0.3);
909    /// let dir = f.add_from_round(-3, Round::Nearest);
910    /// // -3.3 rounded up to -3.25
911    /// assert_eq!(f, -3.25);
912    /// assert_eq!(dir, Ordering::Greater);
913    /// # }
914    /// ```
915    fn add_from_round(&mut self, lhs: Lhs, round: Self::Round) -> Self::Ordering;
916}
917
918/**
919Compound subtraction and assignment with a specified rounding method.
920
921# Examples
922
923```rust
924# #[cfg(feature = "float")] {
925use core::cmp::Ordering;
926use rug::float::Round;
927use rug::ops::SubAssignRound;
928use rug::Float;
929struct F(f64);
930impl SubAssignRound<f64> for F {
931    type Round = Round;
932    type Ordering = Ordering;
933    fn sub_assign_round(&mut self, rhs: f64, round: Round) -> Ordering {
934        let mut f = Float::with_val(53, self.0);
935        let dir = f.sub_assign_round(rhs, round);
936        self.0 = f.to_f64();
937        dir
938    }
939}
940let mut f = F(3.0);
941let dir = f.sub_assign_round(5.0, Round::Nearest);
942// 3.0 - 5.0 = -2.0
943assert_eq!(f.0, -2.0);
944assert_eq!(dir, Ordering::Equal);
945# }
946```
947*/
948pub trait SubAssignRound<Rhs = Self> {
949    /// The rounding method.
950    type Round;
951    /// The direction from rounding.
952    type Ordering;
953    /// Performs the subtraction.
954    ///
955    /// # Examples
956    ///
957    /// ```rust
958    /// # #[cfg(feature = "float")] {
959    /// use core::cmp::Ordering;
960    /// use rug::float::Round;
961    /// use rug::ops::SubAssignRound;
962    /// use rug::Float;
963    /// // only four significant bits
964    /// let mut f = Float::with_val(4, -3);
965    /// let dir = f.sub_assign_round(0.3, Round::Nearest);
966    /// // -3.3 rounded up to -3.25
967    /// assert_eq!(f, -3.25);
968    /// assert_eq!(dir, Ordering::Greater);
969    /// # }
970    /// ```
971    fn sub_assign_round(&mut self, rhs: Rhs, round: Self::Round) -> Self::Ordering;
972}
973
974/**
975Compound subtraction and assignment to the rhs operand with a specified rounding
976method.
977
978# Examples
979
980```rust
981# #[cfg(feature = "float")] {
982use core::cmp::Ordering;
983use rug::float::Round;
984use rug::ops::{SubAssignRound, SubFromRound};
985use rug::Float;
986struct F(f64);
987impl SubFromRound<f64> for F {
988    type Round = Round;
989    type Ordering = Ordering;
990    fn sub_from_round(&mut self, lhs: f64, round: Round) -> Ordering {
991        let mut f = Float::with_val(53, lhs);
992        let dir = f.sub_assign_round(self.0, round);
993        self.0 = f.to_f64();
994        dir
995    }
996}
997let mut f = F(5.0);
998let dir = f.sub_from_round(3.0, Round::Nearest);
999// 3.0 - 5.0 = -2.0
1000assert_eq!(f.0, -2.0);
1001assert_eq!(dir, Ordering::Equal);
1002# }
1003```
1004*/
1005pub trait SubFromRound<Lhs = Self> {
1006    /// The rounding method.
1007    type Round;
1008    /// The direction from rounding.
1009    type Ordering;
1010    /// Performs the subtraction.
1011    ///
1012    /// # Examples
1013    ///
1014    /// ```rust
1015    /// # #[cfg(feature = "float")] {
1016    /// use core::cmp::Ordering;
1017    /// use rug::float::Round;
1018    /// use rug::ops::SubFromRound;
1019    /// use rug::Float;
1020    /// // only four significant bits
1021    /// let mut f = Float::with_val(4, 0.3);
1022    /// let dir = f.sub_from_round(-3, Round::Nearest);
1023    /// // -3.3 rounded up to -3.25
1024    /// assert_eq!(f, -3.25);
1025    /// assert_eq!(dir, Ordering::Greater);
1026    /// # }
1027    /// ```
1028    fn sub_from_round(&mut self, lhs: Lhs, round: Self::Round) -> Self::Ordering;
1029}
1030
1031/**
1032Compound multiplication and assignment with a specified rounding method.
1033
1034# Examples
1035
1036```rust
1037# #[cfg(feature = "float")] {
1038use core::cmp::Ordering;
1039use rug::float::Round;
1040use rug::ops::MulAssignRound;
1041use rug::Float;
1042struct F(f64);
1043impl MulAssignRound<f64> for F {
1044    type Round = Round;
1045    type Ordering = Ordering;
1046    fn mul_assign_round(&mut self, rhs: f64, round: Round) -> Ordering {
1047        let mut f = Float::with_val(53, self.0);
1048        let dir = f.mul_assign_round(rhs, round);
1049        self.0 = f.to_f64();
1050        dir
1051    }
1052}
1053let mut f = F(3.0);
1054let dir = f.mul_assign_round(5.0, Round::Nearest);
1055// 3.0 × 5.0 = 15.0
1056assert_eq!(f.0, 15.0);
1057assert_eq!(dir, Ordering::Equal);
1058# }
1059```
1060*/
1061pub trait MulAssignRound<Rhs = Self> {
1062    /// The rounding method.
1063    type Round;
1064    /// The direction from rounding.
1065    type Ordering;
1066    /// Performs the multiplication.
1067    ///
1068    /// # Examples
1069    ///
1070    /// ```rust
1071    /// # #[cfg(feature = "float")] {
1072    /// use core::cmp::Ordering;
1073    /// use rug::float::Round;
1074    /// use rug::ops::MulAssignRound;
1075    /// use rug::Float;
1076    /// // only four significant bits
1077    /// let mut f = Float::with_val(4, -3);
1078    /// let dir = f.mul_assign_round(13, Round::Nearest);
1079    /// // -39 rounded down to -40
1080    /// assert_eq!(f, -40);
1081    /// assert_eq!(dir, Ordering::Less);
1082    /// # }
1083    /// ```
1084    fn mul_assign_round(&mut self, rhs: Rhs, round: Self::Round) -> Self::Ordering;
1085}
1086
1087/**
1088Compound multiplication and assignment to the rhs operand with a specified
1089rounding method.
1090
1091# Examples
1092
1093```rust
1094# #[cfg(feature = "float")] {
1095use core::cmp::Ordering;
1096use rug::float::Round;
1097use rug::ops::{MulAssignRound, MulFromRound};
1098use rug::Float;
1099struct F(f64);
1100impl MulFromRound<f64> for F {
1101    type Round = Round;
1102    type Ordering = Ordering;
1103    fn mul_from_round(&mut self, lhs: f64, round: Round) -> Ordering {
1104        let mut f = Float::with_val(53, lhs);
1105        let dir = f.mul_assign_round(self.0, round);
1106        self.0 = f.to_f64();
1107        dir
1108    }
1109}
1110let mut f = F(5.0);
1111let dir = f.mul_from_round(3.0, Round::Nearest);
1112// 3.0 × 5.0 = 15.0
1113assert_eq!(f.0, 15.0);
1114assert_eq!(dir, Ordering::Equal);
1115# }
1116```
1117*/
1118pub trait MulFromRound<Lhs = Self> {
1119    /// The rounding method.
1120    type Round;
1121    /// The direction from rounding.
1122    type Ordering;
1123    /// Performs the multiplication.
1124    ///
1125    /// # Examples
1126    ///
1127    /// ```rust
1128    /// # #[cfg(feature = "float")] {
1129    /// use core::cmp::Ordering;
1130    /// use rug::float::Round;
1131    /// use rug::ops::MulFromRound;
1132    /// use rug::Float;
1133    /// // only four significant bits
1134    /// let mut f = Float::with_val(4, 13);
1135    /// let dir = f.mul_from_round(-3, Round::Nearest);
1136    /// // -39 rounded down to -40
1137    /// assert_eq!(f, -40);
1138    /// assert_eq!(dir, Ordering::Less);
1139    /// # }
1140    /// ```
1141    fn mul_from_round(&mut self, lhs: Lhs, round: Self::Round) -> Self::Ordering;
1142}
1143
1144/**
1145Compound division and assignment with a specified rounding method.
1146
1147# Examples
1148
1149```rust
1150# #[cfg(feature = "float")] {
1151use core::cmp::Ordering;
1152use rug::float::Round;
1153use rug::ops::DivAssignRound;
1154use rug::Float;
1155struct F(f64);
1156impl DivAssignRound<f64> for F {
1157    type Round = Round;
1158    type Ordering = Ordering;
1159    fn div_assign_round(&mut self, rhs: f64, round: Round) -> Ordering {
1160        let mut f = Float::with_val(53, self.0);
1161        let dir = f.div_assign_round(rhs, round);
1162        self.0 = f.to_f64();
1163        dir
1164    }
1165}
1166let mut f = F(3.0);
1167let dir = f.div_assign_round(4.0, Round::Nearest);
1168// 3.0 / 4.0 = 0.75
1169assert_eq!(f.0, 0.75);
1170assert_eq!(dir, Ordering::Equal);
1171# }
1172```
1173*/
1174pub trait DivAssignRound<Rhs = Self> {
1175    /// The rounding method.
1176    type Round;
1177    /// The direction from rounding.
1178    type Ordering;
1179    /// Performs the division.
1180    ///
1181    /// # Examples
1182    ///
1183    /// ```rust
1184    /// # #[cfg(feature = "float")] {
1185    /// use core::cmp::Ordering;
1186    /// use rug::float::Round;
1187    /// use rug::ops::DivAssignRound;
1188    /// use rug::Float;
1189    /// // only four significant bits
1190    /// let mut f = Float::with_val(4, -3);
1191    /// let dir = f.div_assign_round(5, Round::Nearest);
1192    /// // -0.6 rounded down to -0.625
1193    /// assert_eq!(f, -0.625);
1194    /// assert_eq!(dir, Ordering::Less);
1195    /// # }
1196    /// ```
1197    fn div_assign_round(&mut self, rhs: Rhs, round: Self::Round) -> Self::Ordering;
1198}
1199
1200/**
1201Compound division and assignment to the rhs operand with a specified rounding
1202method.
1203
1204# Examples
1205
1206```rust
1207# #[cfg(feature = "float")] {
1208use core::cmp::Ordering;
1209use rug::float::Round;
1210use rug::ops::{DivAssignRound, DivFromRound};
1211use rug::Float;
1212struct F(f64);
1213impl DivFromRound<f64> for F {
1214    type Round = Round;
1215    type Ordering = Ordering;
1216    fn div_from_round(&mut self, lhs: f64, round: Round) -> Ordering {
1217        let mut f = Float::with_val(53, lhs);
1218        let dir = f.div_assign_round(self.0, round);
1219        self.0 = f.to_f64();
1220        dir
1221    }
1222}
1223let mut f = F(4.0);
1224let dir = f.div_from_round(3.0, Round::Nearest);
1225// 3.0 / 4.0 = 0.75
1226assert_eq!(f.0, 0.75);
1227assert_eq!(dir, Ordering::Equal);
1228# }
1229```
1230*/
1231pub trait DivFromRound<Lhs = Self> {
1232    /// The rounding method.
1233    type Round;
1234    /// The direction from rounding.
1235    type Ordering;
1236    /// Performs the division.
1237    ///
1238    /// # Examples
1239    ///
1240    /// ```rust
1241    /// # #[cfg(feature = "float")] {
1242    /// use core::cmp::Ordering;
1243    /// use rug::float::Round;
1244    /// use rug::ops::DivFromRound;
1245    /// use rug::Float;
1246    /// // only four significant bits
1247    /// let mut f = Float::with_val(4, 5);
1248    /// let dir = f.div_from_round(-3, Round::Nearest);
1249    /// // -0.6 rounded down to -0.625
1250    /// assert_eq!(f, -0.625);
1251    /// assert_eq!(dir, Ordering::Less);
1252    /// # }
1253    /// ```
1254    fn div_from_round(&mut self, lhs: Lhs, round: Self::Round) -> Self::Ordering;
1255}
1256
1257/**
1258Compound remainder operation and assignment with a specified rounding method.
1259
1260# Examples
1261
1262```rust
1263# #[cfg(feature = "float")] {
1264use core::cmp::Ordering;
1265use rug::float::Round;
1266use rug::ops::RemAssignRound;
1267use rug::Float;
1268struct F(f64);
1269impl RemAssignRound<f64> for F {
1270    type Round = Round;
1271    type Ordering = Ordering;
1272    fn rem_assign_round(&mut self, rhs: f64, round: Round) -> Ordering {
1273        let mut f = Float::with_val(53, self.0);
1274        let dir = f.rem_assign_round(rhs, round);
1275        self.0 = f.to_f64();
1276        dir
1277    }
1278}
1279let mut f = F(3.25);
1280let dir = f.rem_assign_round(1.25, Round::Nearest);
1281// 3.25 % 1.25 = 0.75
1282assert_eq!(f.0, 0.75);
1283assert_eq!(dir, Ordering::Equal);
1284# }
1285```
1286*/
1287pub trait RemAssignRound<Rhs = Self> {
1288    /// The rounding method.
1289    type Round;
1290    /// The direction from rounding.
1291    type Ordering;
1292    /// Performs the remainder operation.
1293    ///
1294    /// # Examples
1295    ///
1296    /// ```rust
1297    /// # #[cfg(feature = "float")] {
1298    /// use core::cmp::Ordering;
1299    /// use rug::float::Round;
1300    /// use rug::ops::RemAssignRound;
1301    /// use rug::Float;
1302    /// // only four significant bits
1303    /// let mut f = Float::with_val(4, 64);
1304    /// let dir = f.rem_assign_round(33, Round::Nearest);
1305    /// // 31 rounded up to 32
1306    /// assert_eq!(f, 32);
1307    /// assert_eq!(dir, Ordering::Greater);
1308    /// # }
1309    /// ```
1310    fn rem_assign_round(&mut self, rhs: Rhs, round: Self::Round) -> Self::Ordering;
1311}
1312
1313/**
1314Compound remainder operation and assignment to the rhs operand with a specified
1315rounding method.
1316
1317# Examples
1318
1319```rust
1320# #[cfg(feature = "float")] {
1321use core::cmp::Ordering;
1322use rug::float::Round;
1323use rug::ops::{RemAssignRound, RemFromRound};
1324use rug::Float;
1325struct F(f64);
1326impl RemFromRound<f64> for F {
1327    type Round = Round;
1328    type Ordering = Ordering;
1329    fn rem_from_round(&mut self, lhs: f64, round: Round) -> Ordering {
1330        let mut f = Float::with_val(53, lhs);
1331        let dir = f.rem_assign_round(self.0, round);
1332        self.0 = f.to_f64();
1333        dir
1334    }
1335}
1336let mut f = F(1.25);
1337let dir = f.rem_from_round(3.25, Round::Nearest);
1338// 3.25 % 1.25 = 0.75
1339assert_eq!(f.0, 0.75);
1340assert_eq!(dir, Ordering::Equal);
1341# }
1342```
1343*/
1344pub trait RemFromRound<Lhs = Self> {
1345    /// The rounding method.
1346    type Round;
1347    /// The direction from rounding.
1348    type Ordering;
1349    /// Performs the remainder operation.
1350    ///
1351    /// # Examples
1352    ///
1353    /// ```rust
1354    /// # #[cfg(feature = "float")] {
1355    /// use core::cmp::Ordering;
1356    /// use rug::float::Round;
1357    /// use rug::ops::RemFromRound;
1358    /// use rug::Float;
1359    /// // only four significant bits
1360    /// let mut f = Float::with_val(4, 32);
1361    /// let dir = f.rem_from_round(17, Round::Nearest);
1362    /// // 17 rounded down to 16
1363    /// assert_eq!(f, 16);
1364    /// assert_eq!(dir, Ordering::Less);
1365    /// # }
1366    /// ```
1367    fn rem_from_round(&mut self, lhs: Lhs, round: Self::Round) -> Self::Ordering;
1368}
1369
1370/**
1371Compound power operation and assignment with a specified rounding method.
1372
1373# Examples
1374
1375```rust
1376# #[cfg(feature = "float")] {
1377use core::cmp::Ordering;
1378use rug::float::Round;
1379use rug::ops::PowAssignRound;
1380use rug::Float;
1381struct F(f64);
1382impl PowAssignRound<f64> for F {
1383    type Round = Round;
1384    type Ordering = Ordering;
1385    fn pow_assign_round(&mut self, rhs: f64, round: Round) -> Ordering {
1386        let mut f = Float::with_val(53, self.0);
1387        let dir = f.pow_assign_round(rhs, round);
1388        self.0 = f.to_f64();
1389        dir
1390    }
1391}
1392let mut f = F(3.0);
1393let dir = f.pow_assign_round(5.0, Round::Nearest);
1394// 3.0 ^ 5.0 = 243.0
1395assert_eq!(f.0, 243.0);
1396assert_eq!(dir, Ordering::Equal);
1397# }
1398```
1399*/
1400pub trait PowAssignRound<Rhs = Self> {
1401    /// The rounding method.
1402    type Round;
1403    /// The direction from rounding.
1404    type Ordering;
1405    /// Performs the power operation.
1406    ///
1407    /// # Examples
1408    ///
1409    /// ```rust
1410    /// # #[cfg(feature = "float")] {
1411    /// use core::cmp::Ordering;
1412    /// use rug::float::Round;
1413    /// use rug::ops::PowAssignRound;
1414    /// use rug::Float;
1415    /// // only four significant bits
1416    /// let mut f = Float::with_val(4, -3);
1417    /// let dir = f.pow_assign_round(5, Round::Nearest);
1418    /// // -243 rounded up to -240
1419    /// assert_eq!(f, -240);
1420    /// assert_eq!(dir, Ordering::Greater);
1421    /// # }
1422    /// ```
1423    fn pow_assign_round(&mut self, rhs: Rhs, round: Self::Round) -> Self::Ordering;
1424}
1425
1426/**
1427Compound power operation and assignment to the rhs operand with a specified
1428rounding method.
1429
1430# Examples
1431
1432```rust
1433# #[cfg(feature = "float")] {
1434use core::cmp::Ordering;
1435use rug::float::Round;
1436use rug::ops::{PowAssignRound, PowFromRound};
1437use rug::Float;
1438struct F(f64);
1439impl PowFromRound<f64> for F {
1440    type Round = Round;
1441    type Ordering = Ordering;
1442    fn pow_from_round(&mut self, lhs: f64, round: Round) -> Ordering {
1443        let mut f = Float::with_val(53, lhs);
1444        let dir = f.pow_assign_round(self.0, round);
1445        self.0 = f.to_f64();
1446        dir
1447    }
1448}
1449let mut f = F(5.0);
1450let dir = f.pow_from_round(3.0, Round::Nearest);
1451// 3.0 ^ 5.0 = 243.0
1452assert_eq!(f.0, 243.0);
1453assert_eq!(dir, Ordering::Equal);
1454# }
1455```
1456*/
1457pub trait PowFromRound<Lhs = Self> {
1458    /// The rounding method.
1459    type Round;
1460    /// The direction from rounding.
1461    type Ordering;
1462    /// Performs the power operation.
1463    ///
1464    /// # Examples
1465    ///
1466    /// ```rust
1467    /// # #[cfg(feature = "float")] {
1468    /// use core::cmp::Ordering;
1469    /// use rug::float::Round;
1470    /// use rug::ops::PowFromRound;
1471    /// use rug::Float;
1472    /// // only four significant bits
1473    /// let mut f = Float::with_val(4, 5);
1474    /// let dir = f.pow_from_round(-3, Round::Nearest);
1475    /// // -243 rounded up to -240
1476    /// assert_eq!(f, -240);
1477    /// assert_eq!(dir, Ordering::Greater);
1478    /// # }
1479    /// ```
1480    fn pow_from_round(&mut self, lhs: Lhs, round: Self::Round) -> Self::Ordering;
1481}
1482
1483/**
1484Rounding variants of division.
1485
1486# Examples
1487
1488```rust
1489use rug::ops::DivRounding;
1490struct I(i32);
1491impl DivRounding<i32> for I {
1492    type Output = i32;
1493    fn div_trunc(self, rhs: i32) -> i32 {
1494        self.0 / rhs
1495    }
1496    fn div_ceil(self, rhs: i32) -> i32 {
1497        let (q, r) = (self.0 / rhs, self.0 % rhs);
1498        let change = if rhs > 0 { r > 0 } else { r < 0 };
1499        if change {
1500            q + 1
1501        } else {
1502            q
1503        }
1504    }
1505    fn div_floor(self, rhs: i32) -> i32 {
1506        let (q, r) = (self.0 / rhs, self.0 % rhs);
1507        let change = if rhs > 0 { r < 0 } else { r > 0 };
1508        if change {
1509            q - 1
1510        } else {
1511            q
1512        }
1513    }
1514    fn div_euc(self, rhs: i32) -> i32 {
1515        let (q, r) = (self.0 / rhs, self.0 % rhs);
1516        if r < 0 {
1517            if rhs < 0 {
1518                q + 1
1519            } else {
1520                q - 1
1521            }
1522        } else {
1523            q
1524        }
1525    }
1526}
1527assert_eq!(I(-10).div_trunc(-3), 3);
1528assert_eq!(I(-10).div_ceil(-3), 4);
1529assert_eq!(I(-10).div_floor(-3), 3);
1530assert_eq!(I(-10).div_euc(-3), 4);
1531```
1532*/
1533pub trait DivRounding<Rhs = Self> {
1534    /// The resulting type from the division operation.
1535    type Output;
1536    /// Performs division, rounding the quotient towards zero.
1537    fn div_trunc(self, rhs: Rhs) -> Self::Output;
1538    /// Performs division, rounding the quotient up.
1539    fn div_ceil(self, rhs: Rhs) -> Self::Output;
1540    /// Performs division, rounding the quotient down.
1541    fn div_floor(self, rhs: Rhs) -> Self::Output;
1542    /// Performs Euclidean division, rounding the quotient so that the
1543    /// remainder cannot be negative.
1544    fn div_euc(self, rhs: Rhs) -> Self::Output;
1545}
1546
1547/**
1548Compound assignment and rounding variants of division.
1549
1550# Examples
1551
1552```rust
1553use rug::ops::DivRoundingAssign;
1554struct I(i32);
1555impl DivRoundingAssign<i32> for I {
1556    fn div_trunc_assign(&mut self, rhs: i32) {
1557        self.0 /= rhs;
1558    }
1559    fn div_ceil_assign(&mut self, rhs: i32) {
1560        let (q, r) = (self.0 / rhs, self.0 % rhs);
1561        let change = if rhs > 0 { r > 0 } else { r < 0 };
1562        self.0 = if change { q + 1 } else { q };
1563    }
1564    fn div_floor_assign(&mut self, rhs: i32) {
1565        let (q, r) = (self.0 / rhs, self.0 % rhs);
1566        let change = if rhs > 0 { r < 0 } else { r > 0 };
1567        self.0 = if change { q - 1 } else { q };
1568    }
1569    fn div_euc_assign(&mut self, rhs: i32) {
1570        let (q, r) = (self.0 / rhs, self.0 % rhs);
1571        self.0 = if r < 0 {
1572            if rhs < 0 {
1573                q + 1
1574            } else {
1575                q - 1
1576            }
1577        } else {
1578            q
1579        };
1580    }
1581}
1582let mut div_floor = I(-10);
1583div_floor.div_floor_assign(3);
1584assert_eq!(div_floor.0, -4);
1585```
1586*/
1587pub trait DivRoundingAssign<Rhs = Self> {
1588    /// Performs division, rounding the quotient towards zero.
1589    fn div_trunc_assign(&mut self, rhs: Rhs);
1590    /// Performs division, rounding the quotient up.
1591    fn div_ceil_assign(&mut self, rhs: Rhs);
1592    /// Performs division, rounding the quotient down.
1593    fn div_floor_assign(&mut self, rhs: Rhs);
1594    /// Performs Euclidean division, rounding the quotient so that the
1595    /// remainder cannot be negative.
1596    fn div_euc_assign(&mut self, rhs: Rhs);
1597}
1598
1599/**
1600Compound assignment to the rhs operand and rounding variants of division.
1601
1602# Examples
1603
1604```rust
1605use rug::ops::DivRoundingFrom;
1606struct I(i32);
1607impl DivRoundingFrom<i32> for I {
1608    fn div_trunc_from(&mut self, lhs: i32) {
1609        self.0 = lhs / self.0;
1610    }
1611    fn div_ceil_from(&mut self, lhs: i32) {
1612        let (q, r) = (lhs / self.0, lhs % self.0);
1613        let change = if self.0 > 0 { r > 0 } else { r < 0 };
1614        self.0 = if change { q + 1 } else { q };
1615    }
1616    fn div_floor_from(&mut self, lhs: i32) {
1617        let (q, r) = (lhs / self.0, lhs % self.0);
1618        let change = if self.0 > 0 { r < 0 } else { r > 0 };
1619        self.0 = if change { q - 1 } else { q };
1620    }
1621    fn div_euc_from(&mut self, lhs: i32) {
1622        let (q, r) = (lhs / self.0, lhs % self.0);
1623        self.0 = if r < 0 {
1624            if self.0 < 0 {
1625                q + 1
1626            } else {
1627                q - 1
1628            }
1629        } else {
1630            q
1631        };
1632    }
1633}
1634let mut div_ceil = I(3);
1635div_ceil.div_ceil_from(10);
1636assert_eq!(div_ceil.0, 4);
1637```
1638*/
1639pub trait DivRoundingFrom<Lhs = Self> {
1640    /// Performs division, rounding the quotient towards zero.
1641    fn div_trunc_from(&mut self, lhs: Lhs);
1642    /// Performs division, rounding the quotient up.
1643    fn div_ceil_from(&mut self, lhs: Lhs);
1644    /// Performs division, rounding the quotient down.
1645    fn div_floor_from(&mut self, lhs: Lhs);
1646    /// Performs Euclidean division, rounding the quotient so that the
1647    /// remainder cannot be negative.
1648    fn div_euc_from(&mut self, lhs: Lhs);
1649}
1650
1651/**
1652Rounding variants of the remainder operation.
1653
1654# Examples
1655
1656```rust
1657use rug::ops::RemRounding;
1658struct I(i32);
1659impl RemRounding<i32> for I {
1660    type Output = i32;
1661    fn rem_trunc(self, rhs: i32) -> i32 {
1662        self.0 % rhs
1663    }
1664    fn rem_ceil(self, rhs: i32) -> i32 {
1665        let r = self.0 % rhs;
1666        let change = if rhs > 0 { r > 0 } else { r < 0 };
1667        if change {
1668            r - rhs
1669        } else {
1670            r
1671        }
1672    }
1673    fn rem_floor(self, rhs: i32) -> i32 {
1674        let r = self.0 % rhs;
1675        let change = if rhs > 0 { r < 0 } else { r > 0 };
1676        if change {
1677            r + rhs
1678        } else {
1679            r
1680        }
1681    }
1682    fn rem_euc(self, rhs: i32) -> i32 {
1683        let r = self.0 % rhs;
1684        if r < 0 {
1685            if rhs < 0 {
1686                r - rhs
1687            } else {
1688                r + rhs
1689            }
1690        } else {
1691            r
1692        }
1693    }
1694}
1695assert_eq!(I(-10).rem_trunc(-3), -1);
1696assert_eq!(I(-10).rem_ceil(-3), 2);
1697assert_eq!(I(-10).rem_floor(-3), -1);
1698assert_eq!(I(-10).rem_euc(-3), 2);
1699```
1700*/
1701pub trait RemRounding<Rhs = Self> {
1702    /// The resulting type from the remainder operation.
1703    type Output;
1704    /// Finds the remainder when the quotient is rounded towards zero.
1705    fn rem_trunc(self, rhs: Rhs) -> Self::Output;
1706    /// Finds the remainder when the quotient is rounded up.
1707    fn rem_ceil(self, rhs: Rhs) -> Self::Output;
1708    /// Finds the remainder when the quotient is rounded down.
1709    fn rem_floor(self, rhs: Rhs) -> Self::Output;
1710    /// Finds the positive remainder from Euclidean division.
1711    fn rem_euc(self, rhs: Rhs) -> Self::Output;
1712}
1713
1714/**
1715Compound assignment and rounding variants of the remainder operation.
1716
1717# Examples
1718
1719```rust
1720use rug::ops::RemRoundingAssign;
1721struct I(i32);
1722impl RemRoundingAssign<i32> for I {
1723    fn rem_trunc_assign(&mut self, rhs: i32) {
1724        self.0 %= rhs;
1725    }
1726    fn rem_ceil_assign(&mut self, rhs: i32) {
1727        let r = self.0 % rhs;
1728        let change = if rhs > 0 { r > 0 } else { r < 0 };
1729        self.0 = if change { r - rhs } else { r };
1730    }
1731    fn rem_floor_assign(&mut self, rhs: i32) {
1732        let r = self.0 % rhs;
1733        let change = if rhs > 0 { r < 0 } else { r > 0 };
1734        self.0 = if change { r + rhs } else { r };
1735    }
1736    fn rem_euc_assign(&mut self, rhs: i32) {
1737        let r = self.0 % rhs;
1738        self.0 = if r < 0 {
1739            if rhs < 0 {
1740                r - rhs
1741            } else {
1742                r + rhs
1743            }
1744        } else {
1745            r
1746        };
1747    }
1748}
1749let mut rem_floor = I(-10);
1750rem_floor.rem_floor_assign(3);
1751assert_eq!(rem_floor.0, 2);
1752```
1753*/
1754pub trait RemRoundingAssign<Rhs = Self> {
1755    /// Finds the remainder when the quotient is rounded towards zero.
1756    fn rem_trunc_assign(&mut self, rhs: Rhs);
1757    /// Finds the remainder when the quotient is rounded up.
1758    fn rem_ceil_assign(&mut self, rhs: Rhs);
1759    /// Finds the remainder when the quotient is rounded down.
1760    fn rem_floor_assign(&mut self, rhs: Rhs);
1761    /// Finds the positive remainder from Euclidean division.
1762    fn rem_euc_assign(&mut self, rhs: Rhs);
1763}
1764
1765/**
1766Compound assignment to the rhs operand and rounding variants of the remainder
1767operation.
1768
1769# Examples
1770
1771```rust
1772use rug::ops::RemRoundingFrom;
1773struct I(i32);
1774impl RemRoundingFrom<i32> for I {
1775    fn rem_trunc_from(&mut self, lhs: i32) {
1776        self.0 = lhs % self.0;
1777    }
1778    fn rem_ceil_from(&mut self, lhs: i32) {
1779        let r = lhs % self.0;
1780        let change = if self.0 > 0 { r > 0 } else { r < 0 };
1781        self.0 = if change { r - self.0 } else { r };
1782    }
1783    fn rem_floor_from(&mut self, lhs: i32) {
1784        let r = lhs % self.0;
1785        let change = if self.0 > 0 { r < 0 } else { r > 0 };
1786        self.0 = if change { r + self.0 } else { r };
1787    }
1788    fn rem_euc_from(&mut self, lhs: i32) {
1789        let r = lhs % self.0;
1790        self.0 = if r < 0 {
1791            if self.0 < 0 {
1792                r - self.0
1793            } else {
1794                r + self.0
1795            }
1796        } else {
1797            r
1798        };
1799    }
1800}
1801let mut rem_ceil = I(3);
1802rem_ceil.rem_ceil_from(10);
1803assert_eq!(rem_ceil.0, -2);
1804```
1805*/
1806pub trait RemRoundingFrom<Lhs = Self> {
1807    /// Finds the remainder when the quotient is rounded towards zero.
1808    fn rem_trunc_from(&mut self, lhs: Lhs);
1809    /// Finds the remainder when the quotient is rounded up.
1810    fn rem_ceil_from(&mut self, lhs: Lhs);
1811    /// Finds the remainder when the quotient is rounded down.
1812    fn rem_floor_from(&mut self, lhs: Lhs);
1813    /// Finds the positive remainder from Euclidean division.
1814    fn rem_euc_from(&mut self, lhs: Lhs);
1815}