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}