1use crate::{
4 add,
5 arch::word::Word,
6 buffer::Buffer,
7 helper_macros,
8 ibig::IBig,
9 primitive::{PrimitiveSigned, PrimitiveUnsigned},
10 sign::Sign::*,
11 ubig::{Repr::*, UBig},
12};
13use core::{
14 mem,
15 ops::{Add, AddAssign, Sub, SubAssign},
16};
17
18impl Add<UBig> for UBig {
19 type Output = UBig;
20
21 #[inline]
22 fn add(self, rhs: UBig) -> UBig {
23 match (self.into_repr(), rhs.into_repr()) {
24 (Small(word0), Small(word1)) => UBig::add_word(word0, word1),
25 (Small(word0), Large(buffer1)) => UBig::add_large_word(buffer1, word0),
26 (Large(buffer0), Small(word1)) => UBig::add_large_word(buffer0, word1),
27 (Large(buffer0), Large(buffer1)) => {
28 if buffer0.len() >= buffer1.len() {
29 UBig::add_large(buffer0, &buffer1)
30 } else {
31 UBig::add_large(buffer1, &buffer0)
32 }
33 }
34 }
35 }
36}
37
38impl Add<&UBig> for UBig {
39 type Output = UBig;
40
41 #[inline]
42 fn add(self, rhs: &UBig) -> UBig {
43 match (self.into_repr(), rhs.repr()) {
44 (Small(word0), Small(word1)) => UBig::add_word(word0, *word1),
45 (Small(word0), Large(buffer1)) => UBig::add_large_word(buffer1.clone(), word0),
46 (Large(buffer0), Small(word1)) => UBig::add_large_word(buffer0, *word1),
47 (Large(buffer0), Large(buffer1)) => UBig::add_large(buffer0, buffer1),
48 }
49 }
50}
51
52impl Add<UBig> for &UBig {
53 type Output = UBig;
54
55 #[inline]
56 fn add(self, rhs: UBig) -> UBig {
57 rhs.add(self)
58 }
59}
60
61impl Add<&UBig> for &UBig {
62 type Output = UBig;
63
64 #[inline]
65 fn add(self, rhs: &UBig) -> UBig {
66 match (self.repr(), rhs.repr()) {
67 (Small(word0), Small(word1)) => UBig::add_word(*word0, *word1),
68 (Small(word0), Large(buffer1)) => UBig::add_large_word(buffer1.clone(), *word0),
69 (Large(buffer0), Small(word1)) => UBig::add_large_word(buffer0.clone(), *word1),
70 (Large(buffer0), Large(buffer1)) => {
71 if buffer0.len() >= buffer1.len() {
72 UBig::add_large(buffer0.clone(), buffer1)
73 } else {
74 UBig::add_large(buffer1.clone(), buffer0)
75 }
76 }
77 }
78 }
79}
80
81impl AddAssign<UBig> for UBig {
82 #[inline]
83 fn add_assign(&mut self, rhs: UBig) {
84 *self = mem::take(self) + rhs;
85 }
86}
87
88impl AddAssign<&UBig> for UBig {
89 #[inline]
90 fn add_assign(&mut self, rhs: &UBig) {
91 *self = mem::take(self) + rhs;
92 }
93}
94
95impl Sub<UBig> for UBig {
96 type Output = UBig;
97
98 #[inline]
99 fn sub(self, rhs: UBig) -> UBig {
100 match (self.into_repr(), rhs.into_repr()) {
101 (Small(word0), Small(word1)) => UBig::sub_word(word0, word1),
102 (Small(_), Large(_)) => UBig::panic_negative(),
103 (Large(buffer0), Small(word1)) => UBig::sub_large_word(buffer0, word1),
104 (Large(buffer0), Large(buffer1)) => UBig::sub_large(buffer0, &buffer1),
105 }
106 }
107}
108
109impl Sub<&UBig> for UBig {
110 type Output = UBig;
111
112 #[inline]
113 fn sub(self, rhs: &UBig) -> UBig {
114 match (self.into_repr(), rhs.repr()) {
115 (Small(word0), Small(word1)) => UBig::sub_word(word0, *word1),
116 (Small(_), Large(_)) => UBig::panic_negative(),
117 (Large(buffer0), Small(word1)) => UBig::sub_large_word(buffer0, *word1),
118 (Large(buffer0), Large(buffer1)) => UBig::sub_large(buffer0, buffer1),
119 }
120 }
121}
122
123impl Sub<UBig> for &UBig {
124 type Output = UBig;
125
126 #[inline]
127 fn sub(self, rhs: UBig) -> UBig {
128 match (self.repr(), rhs.into_repr()) {
129 (Small(word0), Small(word1)) => UBig::sub_word(*word0, word1),
130 (Small(_), Large(_)) => UBig::panic_negative(),
131 (Large(buffer0), Small(word1)) => UBig::sub_large_word(buffer0.clone(), word1),
132 (Large(buffer0), Large(buffer1)) => UBig::sub_large_ref_val(buffer0, buffer1),
133 }
134 }
135}
136
137impl Sub<&UBig> for &UBig {
138 type Output = UBig;
139
140 #[inline]
141 fn sub(self, rhs: &UBig) -> UBig {
142 match (self.repr(), rhs.repr()) {
143 (Small(word0), Small(word1)) => UBig::sub_word(*word0, *word1),
144 (Small(_), Large(_)) => UBig::panic_negative(),
145 (Large(buffer0), Small(word1)) => UBig::sub_large_word(buffer0.clone(), *word1),
146 (Large(buffer0), Large(buffer1)) => UBig::sub_large(buffer0.clone(), buffer1),
147 }
148 }
149}
150
151impl SubAssign<UBig> for UBig {
152 #[inline]
153 fn sub_assign(&mut self, rhs: UBig) {
154 *self = mem::take(self) - rhs;
155 }
156}
157
158impl SubAssign<&UBig> for UBig {
159 #[inline]
160 fn sub_assign(&mut self, rhs: &UBig) {
161 *self = mem::take(self) - rhs;
162 }
163}
164
165impl Add<IBig> for IBig {
166 type Output = IBig;
167
168 #[inline]
169 fn add(self, rhs: IBig) -> IBig {
170 let (sign0, mag0) = self.into_sign_magnitude();
171 let (sign1, mag1) = rhs.into_sign_magnitude();
172 match (sign0, sign1) {
173 (Positive, Positive) => IBig::from(mag0 + mag1),
174 (Positive, Negative) => IBig::sub_ubig_val_val(mag0, mag1),
175 (Negative, Positive) => IBig::sub_ubig_val_val(mag1, mag0),
176 (Negative, Negative) => -IBig::from(mag0 + mag1),
177 }
178 }
179}
180
181impl Add<&IBig> for IBig {
182 type Output = IBig;
183
184 #[inline]
185 fn add(self, rhs: &IBig) -> IBig {
186 let (sign0, mag0) = self.into_sign_magnitude();
187 let (sign1, mag1) = (rhs.sign(), rhs.magnitude());
188 match (sign0, sign1) {
189 (Positive, Positive) => IBig::from(mag0 + mag1),
190 (Positive, Negative) => IBig::sub_ubig_val_ref(mag0, mag1),
191 (Negative, Positive) => -IBig::sub_ubig_val_ref(mag0, mag1),
192 (Negative, Negative) => -IBig::from(mag0 + mag1),
193 }
194 }
195}
196
197impl Add<IBig> for &IBig {
198 type Output = IBig;
199
200 #[inline]
201 fn add(self, rhs: IBig) -> IBig {
202 rhs.add(self)
203 }
204}
205
206impl Add<&IBig> for &IBig {
207 type Output = IBig;
208
209 #[inline]
210 fn add(self, rhs: &IBig) -> IBig {
211 let (sign0, mag0) = (self.sign(), self.magnitude());
212 let (sign1, mag1) = (rhs.sign(), rhs.magnitude());
213 match (sign0, sign1) {
214 (Positive, Positive) => IBig::from(mag0 + mag1),
215 (Positive, Negative) => IBig::sub_ubig_ref_ref(mag0, mag1),
216 (Negative, Positive) => IBig::sub_ubig_ref_ref(mag1, mag0),
217 (Negative, Negative) => -IBig::from(mag0 + mag1),
218 }
219 }
220}
221
222impl AddAssign<IBig> for IBig {
223 #[inline]
224 fn add_assign(&mut self, rhs: IBig) {
225 *self = mem::take(self) + rhs;
226 }
227}
228
229impl AddAssign<&IBig> for IBig {
230 #[inline]
231 fn add_assign(&mut self, rhs: &IBig) {
232 *self = mem::take(self) + rhs;
233 }
234}
235
236impl Sub<IBig> for IBig {
237 type Output = IBig;
238
239 #[inline]
240 fn sub(self, rhs: IBig) -> IBig {
241 self + -rhs
242 }
243}
244
245impl Sub<&IBig> for IBig {
246 type Output = IBig;
247
248 #[inline]
249 fn sub(self, rhs: &IBig) -> IBig {
250 -(-self + rhs)
251 }
252}
253
254impl Sub<IBig> for &IBig {
255 type Output = IBig;
256
257 #[inline]
258 fn sub(self, rhs: IBig) -> IBig {
259 self + -rhs
260 }
261}
262
263impl Sub<&IBig> for &IBig {
264 type Output = IBig;
265
266 #[inline]
267 fn sub(self, rhs: &IBig) -> IBig {
268 let (sign0, mag0) = (self.sign(), self.magnitude());
269 let (sign1, mag1) = (rhs.sign(), rhs.magnitude());
270 match (sign0, sign1) {
271 (Positive, Positive) => IBig::sub_ubig_ref_ref(mag0, mag1),
272 (Positive, Negative) => IBig::from(mag0 + mag1),
273 (Negative, Positive) => -IBig::from(mag0 + mag1),
274 (Negative, Negative) => IBig::sub_ubig_ref_ref(mag1, mag0),
275 }
276 }
277}
278
279impl SubAssign<IBig> for IBig {
280 #[inline]
281 fn sub_assign(&mut self, rhs: IBig) {
282 *self = mem::take(self) - rhs;
283 }
284}
285
286impl SubAssign<&IBig> for IBig {
287 #[inline]
288 fn sub_assign(&mut self, rhs: &IBig) {
289 *self = mem::take(self) - rhs;
290 }
291}
292
293macro_rules! impl_add_ubig_unsigned {
294 ($t:ty) => {
295 impl Add<$t> for UBig {
296 type Output = UBig;
297
298 #[inline]
299 fn add(self, rhs: $t) -> UBig {
300 self.add_unsigned(rhs)
301 }
302 }
303
304 impl Add<$t> for &UBig {
305 type Output = UBig;
306
307 #[inline]
308 fn add(self, rhs: $t) -> UBig {
309 self.add_ref_unsigned(rhs)
310 }
311 }
312
313 helper_macros::forward_binop_second_arg_by_value!(impl Add<$t> for UBig, add);
314 helper_macros::forward_binop_swap_args!(impl Add<UBig> for $t, add);
315
316 impl AddAssign<$t> for UBig {
317 #[inline]
318 fn add_assign(&mut self, rhs: $t) {
319 self.add_assign_unsigned(rhs)
320 }
321 }
322
323 helper_macros::forward_binop_assign_arg_by_value!(impl AddAssign<$t> for UBig, add_assign);
324
325 impl Sub<$t> for UBig {
326 type Output = UBig;
327
328 #[inline]
329 fn sub(self, rhs: $t) -> UBig {
330 self.sub_unsigned(rhs)
331 }
332 }
333
334 impl Sub<$t> for &UBig {
335 type Output = UBig;
336
337 #[inline]
338 fn sub(self, rhs: $t) -> UBig {
339 self.sub_ref_unsigned(rhs)
340 }
341 }
342
343 helper_macros::forward_binop_second_arg_by_value!(impl Sub<$t> for UBig, sub);
344
345 impl SubAssign<$t> for UBig {
346 #[inline]
347 fn sub_assign(&mut self, rhs: $t) {
348 self.sub_assign_unsigned(rhs)
349 }
350 }
351
352 helper_macros::forward_binop_assign_arg_by_value!(impl SubAssign<$t> for UBig, sub_assign);
353 };
354}
355
356impl_add_ubig_unsigned!(u8);
357impl_add_ubig_unsigned!(u16);
358impl_add_ubig_unsigned!(u32);
359impl_add_ubig_unsigned!(u64);
360impl_add_ubig_unsigned!(u128);
361impl_add_ubig_unsigned!(usize);
362
363macro_rules! impl_add_ubig_signed {
364 ($t:ty) => {
365 impl Add<$t> for UBig {
366 type Output = UBig;
367
368 #[inline]
369 fn add(self, rhs: $t) -> UBig {
370 self.add_signed(rhs)
371 }
372 }
373
374 impl Add<$t> for &UBig {
375 type Output = UBig;
376
377 #[inline]
378 fn add(self, rhs: $t) -> UBig {
379 self.add_ref_signed(rhs)
380 }
381 }
382
383 helper_macros::forward_binop_second_arg_by_value!(impl Add<$t> for UBig, add);
384 helper_macros::forward_binop_swap_args!(impl Add<UBig> for $t, add);
385
386 impl AddAssign<$t> for UBig {
387 #[inline]
388 fn add_assign(&mut self, rhs: $t) {
389 self.add_assign_signed(rhs)
390 }
391 }
392
393 helper_macros::forward_binop_assign_arg_by_value!(impl AddAssign<$t> for UBig, add_assign);
394
395 impl Sub<$t> for UBig {
396 type Output = UBig;
397
398 #[inline]
399 fn sub(self, rhs: $t) -> UBig {
400 self.sub_signed(rhs)
401 }
402 }
403
404 impl Sub<$t> for &UBig {
405 type Output = UBig;
406
407 #[inline]
408 fn sub(self, rhs: $t) -> UBig {
409 self.sub_ref_signed(rhs)
410 }
411 }
412
413 helper_macros::forward_binop_second_arg_by_value!(impl Sub<$t> for UBig, sub);
414
415 impl SubAssign<$t> for UBig {
416 #[inline]
417 fn sub_assign(&mut self, rhs: $t) {
418 self.sub_assign_signed(rhs)
419 }
420 }
421
422 helper_macros::forward_binop_assign_arg_by_value!(impl SubAssign<$t> for UBig, sub_assign);
423 };
424}
425
426impl_add_ubig_signed!(i8);
427impl_add_ubig_signed!(i16);
428impl_add_ubig_signed!(i32);
429impl_add_ubig_signed!(i64);
430impl_add_ubig_signed!(i128);
431impl_add_ubig_signed!(isize);
432
433macro_rules! impl_add_ibig_primitive {
434 ($t:ty) => {
435 impl Add<$t> for IBig {
436 type Output = IBig;
437
438 #[inline]
439 fn add(self, rhs: $t) -> IBig {
440 self.add_primitive(rhs)
441 }
442 }
443
444 impl Add<$t> for &IBig {
445 type Output = IBig;
446
447 #[inline]
448 fn add(self, rhs: $t) -> IBig {
449 self.add_ref_primitive(rhs)
450 }
451 }
452
453 helper_macros::forward_binop_second_arg_by_value!(impl Add<$t> for IBig, add);
454 helper_macros::forward_binop_swap_args!(impl Add<IBig> for $t, add);
455
456 impl AddAssign<$t> for IBig {
457 #[inline]
458 fn add_assign(&mut self, rhs: $t) {
459 self.add_assign_primitive(rhs)
460 }
461 }
462
463 helper_macros::forward_binop_assign_arg_by_value!(impl AddAssign<$t> for IBig, add_assign);
464
465 impl Sub<$t> for IBig {
466 type Output = IBig;
467
468 #[inline]
469 fn sub(self, rhs: $t) -> IBig {
470 self.sub_primitive(rhs)
471 }
472 }
473
474 impl Sub<$t> for &IBig {
475 type Output = IBig;
476
477 #[inline]
478 fn sub(self, rhs: $t) -> IBig {
479 self.sub_ref_primitive(rhs)
480 }
481 }
482
483 impl Sub<IBig> for $t {
484 type Output = IBig;
485
486 #[inline]
487 fn sub(self, rhs: IBig) -> IBig {
488 rhs.sub_from_primitive(self)
489 }
490 }
491
492 impl Sub<&IBig> for $t {
493 type Output = IBig;
494
495 #[inline]
496 fn sub(self, rhs: &IBig) -> IBig {
497 rhs.sub_ref_from_primitive(self)
498 }
499 }
500
501 helper_macros::forward_binop_second_arg_by_value!(impl Sub<$t> for IBig, sub);
502 helper_macros::forward_binop_first_arg_by_value!(impl Sub<IBig> for $t, sub);
503
504 impl SubAssign<$t> for IBig {
505 #[inline]
506 fn sub_assign(&mut self, rhs: $t) {
507 self.sub_assign_primitive(rhs)
508 }
509 }
510
511 helper_macros::forward_binop_assign_arg_by_value!(impl SubAssign<$t> for IBig, sub_assign);
512 };
513}
514
515impl_add_ibig_primitive!(u8);
516impl_add_ibig_primitive!(u16);
517impl_add_ibig_primitive!(u32);
518impl_add_ibig_primitive!(u64);
519impl_add_ibig_primitive!(u128);
520impl_add_ibig_primitive!(usize);
521impl_add_ibig_primitive!(i8);
522impl_add_ibig_primitive!(i16);
523impl_add_ibig_primitive!(i32);
524impl_add_ibig_primitive!(i64);
525impl_add_ibig_primitive!(i128);
526impl_add_ibig_primitive!(isize);
527
528impl UBig {
529 #[inline]
531 fn add_word(a: Word, b: Word) -> UBig {
532 let (res, overflow) = a.overflowing_add(b);
533 if overflow {
534 let mut buffer = Buffer::allocate(2);
535 buffer.push(res);
536 buffer.push(1);
537 buffer.into()
538 } else {
539 UBig::from_word(res)
540 }
541 }
542
543 fn add_large_word(mut buffer: Buffer, rhs: Word) -> UBig {
545 debug_assert!(buffer.len() >= 2);
546 if add::add_word_in_place(&mut buffer, rhs) {
547 buffer.push_may_reallocate(1);
548 }
549 buffer.into()
550 }
551
552 fn add_large(mut buffer: Buffer, rhs: &[Word]) -> UBig {
554 let n = buffer.len().min(rhs.len());
555 let overflow = add::add_same_len_in_place(&mut buffer[..n], &rhs[..n]);
556 if rhs.len() > n {
557 buffer.ensure_capacity(rhs.len());
558 buffer.extend(&rhs[n..]);
559 }
560 if overflow && add::add_one_in_place(&mut buffer[n..]) {
561 buffer.push_may_reallocate(1);
562 }
563 buffer.into()
564 }
565
566 #[inline]
568 fn sub_word(a: Word, b: Word) -> UBig {
569 match a.checked_sub(b) {
570 Some(res) => UBig::from_word(res),
571 None => UBig::panic_negative(),
572 }
573 }
574
575 fn sub_large_word(mut lhs: Buffer, rhs: Word) -> UBig {
576 let overflow = add::sub_word_in_place(&mut lhs, rhs);
577 assert!(!overflow);
578 lhs.into()
579 }
580
581 fn sub_large(mut lhs: Buffer, rhs: &[Word]) -> UBig {
582 if lhs.len() < rhs.len() || add::sub_in_place(&mut lhs, rhs) {
583 UBig::panic_negative();
584 }
585 lhs.into()
586 }
587
588 fn sub_large_ref_val(lhs: &[Word], mut rhs: Buffer) -> UBig {
589 let n = rhs.len();
590 if lhs.len() < n {
591 UBig::panic_negative();
592 }
593 let borrow = add::sub_same_len_in_place_swap(&lhs[..n], &mut rhs);
594 rhs.ensure_capacity(lhs.len());
595 rhs.extend(&lhs[n..]);
596 if borrow && add::sub_one_in_place(&mut rhs[n..]) {
597 UBig::panic_negative();
598 }
599 rhs.into()
600 }
601
602 #[inline]
603 fn add_unsigned<T: PrimitiveUnsigned>(self, rhs: T) -> UBig {
604 self + UBig::from_unsigned(rhs)
605 }
606
607 #[inline]
608 fn add_ref_unsigned<T: PrimitiveUnsigned>(&self, rhs: T) -> UBig {
609 self + UBig::from_unsigned(rhs)
610 }
611
612 #[inline]
613 fn add_assign_unsigned<T: PrimitiveUnsigned>(&mut self, rhs: T) {
614 *self += UBig::from_unsigned(rhs)
615 }
616
617 #[inline]
618 fn sub_unsigned<T: PrimitiveUnsigned>(self, rhs: T) -> UBig {
619 self - UBig::from_unsigned(rhs)
620 }
621
622 #[inline]
623 fn sub_ref_unsigned<T: PrimitiveUnsigned>(&self, rhs: T) -> UBig {
624 self - UBig::from_unsigned(rhs)
625 }
626
627 #[inline]
628 fn sub_assign_unsigned<T: PrimitiveUnsigned>(&mut self, rhs: T) {
629 *self -= UBig::from_unsigned(rhs)
630 }
631
632 #[inline]
633 fn add_signed<T: PrimitiveSigned>(self, rhs: T) -> UBig {
634 UBig::from_ibig_panic_on_overflow(IBig::from(self) + IBig::from_signed(rhs))
635 }
636
637 #[inline]
638 fn add_ref_signed<T: PrimitiveSigned>(&self, rhs: T) -> UBig {
639 UBig::from_ibig_panic_on_overflow(IBig::from(self) + IBig::from_signed(rhs))
640 }
641
642 #[inline]
643 fn add_assign_signed<T: PrimitiveSigned>(&mut self, rhs: T) {
644 *self = mem::take(self).add_signed(rhs)
645 }
646
647 #[inline]
648 fn sub_signed<T: PrimitiveSigned>(self, rhs: T) -> UBig {
649 UBig::from_ibig_panic_on_overflow(IBig::from(self) - IBig::from_signed(rhs))
650 }
651
652 #[inline]
653 fn sub_ref_signed<T: PrimitiveSigned>(&self, rhs: T) -> UBig {
654 UBig::from_ibig_panic_on_overflow(IBig::from(self) - IBig::from_signed(rhs))
655 }
656
657 #[inline]
658 fn sub_assign_signed<T: PrimitiveSigned>(&mut self, rhs: T) {
659 *self = mem::take(self).sub_signed(rhs)
660 }
661}
662
663impl IBig {
664 #[inline]
665 fn sub_ubig_val_val(lhs: UBig, rhs: UBig) -> IBig {
666 match (lhs.into_repr(), rhs.into_repr()) {
667 (Small(word0), Small(word1)) => IBig::sub_word_word(word0, word1),
668 (Small(word0), Large(buffer1)) => -IBig::sub_large_word(buffer1, word0),
669 (Large(buffer0), Small(word1)) => IBig::sub_large_word(buffer0, word1),
670 (Large(buffer0), Large(buffer1)) => {
671 if buffer0.len() >= buffer1.len() {
672 IBig::sub_large(buffer0, &buffer1)
673 } else {
674 -IBig::sub_large(buffer1, &buffer0)
675 }
676 }
677 }
678 }
679
680 #[inline]
681 fn sub_ubig_val_ref(lhs: UBig, rhs: &UBig) -> IBig {
682 match (lhs.into_repr(), rhs.repr()) {
683 (Small(word0), Small(word1)) => IBig::sub_word_word(word0, *word1),
684 (Small(word0), Large(buffer1)) => -IBig::sub_large_word(buffer1.clone(), word0),
685 (Large(buffer0), Small(word1)) => IBig::sub_large_word(buffer0, *word1),
686 (Large(buffer0), Large(buffer1)) => IBig::sub_large(buffer0, buffer1),
687 }
688 }
689
690 #[inline]
691 fn sub_ubig_ref_ref(lhs: &UBig, rhs: &UBig) -> IBig {
692 match (lhs.repr(), rhs.repr()) {
693 (Small(word0), Small(word1)) => IBig::sub_word_word(*word0, *word1),
694 (Small(word0), Large(buffer1)) => -IBig::sub_large_word(buffer1.clone(), *word0),
695 (Large(buffer0), Small(word1)) => IBig::sub_large_word(buffer0.clone(), *word1),
696 (Large(buffer0), Large(buffer1)) => {
697 if buffer0.len() >= buffer1.len() {
698 IBig::sub_large(buffer0.clone(), buffer1)
699 } else {
700 -IBig::sub_large(buffer1.clone(), buffer0)
701 }
702 }
703 }
704 }
705
706 #[inline]
707 fn sub_word_word(lhs: Word, rhs: Word) -> IBig {
708 let (val, overflow) = lhs.overflowing_sub(rhs);
709 if !overflow {
710 IBig::from(val)
711 } else {
712 -IBig::from(val.wrapping_neg())
713 }
714 }
715
716 fn sub_large_word(lhs: Buffer, rhs: Word) -> IBig {
717 UBig::sub_large_word(lhs, rhs).into()
718 }
719
720 fn sub_large(mut lhs: Buffer, rhs: &[Word]) -> IBig {
721 if lhs.len() >= rhs.len() {
722 let sign = add::sub_in_place_with_sign(&mut lhs, rhs);
723 IBig::from_sign_magnitude(sign, lhs.into())
724 } else {
725 let res = UBig::sub_large_ref_val(rhs, lhs);
726 IBig::from_sign_magnitude(Negative, res)
727 }
728 }
729
730 #[inline]
731 fn add_primitive<T>(self, rhs: T) -> IBig
732 where
733 IBig: From<T>,
734 {
735 self + IBig::from(rhs)
736 }
737
738 #[inline]
739 fn add_ref_primitive<T>(&self, rhs: T) -> IBig
740 where
741 IBig: From<T>,
742 {
743 self + IBig::from(rhs)
744 }
745
746 #[inline]
747 fn add_assign_primitive<T>(&mut self, rhs: T)
748 where
749 IBig: From<T>,
750 {
751 *self += IBig::from(rhs)
752 }
753
754 #[inline]
755 fn sub_primitive<T>(self, rhs: T) -> IBig
756 where
757 IBig: From<T>,
758 {
759 self - IBig::from(rhs)
760 }
761
762 #[inline]
763 fn sub_ref_primitive<T>(&self, rhs: T) -> IBig
764 where
765 IBig: From<T>,
766 {
767 self - IBig::from(rhs)
768 }
769
770 #[inline]
771 fn sub_assign_primitive<T>(&mut self, rhs: T)
772 where
773 IBig: From<T>,
774 {
775 *self -= IBig::from(rhs)
776 }
777
778 #[inline]
779 fn sub_from_primitive<T>(self, rhs: T) -> IBig
780 where
781 IBig: From<T>,
782 {
783 IBig::from(rhs) - self
784 }
785
786 #[inline]
787 fn sub_ref_from_primitive<T>(&self, rhs: T) -> IBig
788 where
789 IBig: From<T>,
790 {
791 IBig::from(rhs) - self
792 }
793}