Skip to content

Commit f58cef3

Browse files
committed
Move sub_sign to its sole use in multiplication
1 parent 1c43928 commit f58cef3

File tree

2 files changed

+45
-45
lines changed

2 files changed

+45
-45
lines changed

src/biguint/multiplication.rs

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
use super::addition::{__add2, add2};
2-
use super::subtraction::{sub2, sub_sign};
2+
use super::subtraction::sub2;
33
#[cfg(not(u64_digit))]
44
use super::u32_from_u128;
5-
use super::{biguint_from_vec, BigUint};
5+
use super::{biguint_from_vec, cmp_slice, BigUint};
66

77
use crate::big_digit::{self, BigDigit, DoubleBigDigit};
8-
use crate::bigint::Sign::{Minus, NoSign, Plus};
8+
use crate::Sign::{self, Minus, NoSign, Plus};
99
use crate::{BigInt, UsizePromotion};
1010

11+
use core::cmp::Ordering;
1112
use core::iter::Product;
1213
use core::ops::{Mul, MulAssign};
13-
use num_traits::{CheckedMul, One};
14+
use num_traits::{CheckedMul, One, Zero};
1415

1516
#[inline]
1617
pub(super) fn mac_with_carry(
@@ -335,6 +336,26 @@ fn scalar_mul(a: &mut [BigDigit], b: BigDigit) -> BigDigit {
335336
carry as BigDigit
336337
}
337338

339+
fn sub_sign(mut a: &[BigDigit], mut b: &[BigDigit]) -> (Sign, BigUint) {
340+
// Normalize:
341+
a = &a[..a.iter().rposition(|&x| x != 0).map_or(0, |i| i + 1)];
342+
b = &b[..b.iter().rposition(|&x| x != 0).map_or(0, |i| i + 1)];
343+
344+
match cmp_slice(a, b) {
345+
Ordering::Greater => {
346+
let mut a = a.to_vec();
347+
sub2(&mut a, b);
348+
(Plus, biguint_from_vec(a))
349+
}
350+
Ordering::Less => {
351+
let mut b = b.to_vec();
352+
sub2(&mut b, a);
353+
(Minus, biguint_from_vec(b))
354+
}
355+
Ordering::Equal => (NoSign, Zero::zero()),
356+
}
357+
}
358+
338359
forward_all_binop_to_ref_ref!(impl Mul for BigUint, mul);
339360
forward_val_assign!(impl MulAssign for BigUint, mul_assign);
340361

@@ -465,3 +486,22 @@ impl CheckedMul for BigUint {
465486
}
466487

467488
impl_product_iter_type!(BigUint);
489+
490+
#[test]
491+
fn test_sub_sign() {
492+
use crate::BigInt;
493+
use num_traits::Num;
494+
495+
fn sub_sign_i(a: &[BigDigit], b: &[BigDigit]) -> BigInt {
496+
let (sign, val) = sub_sign(a, b);
497+
BigInt::from_biguint(sign, val)
498+
}
499+
500+
let a = BigUint::from_str_radix("265252859812191058636308480000000", 10).unwrap();
501+
let b = BigUint::from_str_radix("26525285981219105863630848000000", 10).unwrap();
502+
let a_i = BigInt::from(a.clone());
503+
let b_i = BigInt::from(b.clone());
504+
505+
assert_eq!(sub_sign_i(&a.data[..], &b.data[..]), &a_i - &b_i);
506+
assert_eq!(sub_sign_i(&b.data[..], &a.data[..]), &b_i - &a_i);
507+
}

src/biguint/subtraction.rs

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
#[cfg(not(u64_digit))]
22
use super::u32_from_u128;
3-
use super::{biguint_from_vec, cmp_slice, BigUint};
3+
use super::BigUint;
44

55
use crate::big_digit::{self, BigDigit};
6-
use crate::Sign::{self, Minus, NoSign, Plus};
76
use crate::UsizePromotion;
87

98
use core::cmp::Ordering::{Equal, Greater, Less};
@@ -105,26 +104,6 @@ fn sub2rev(a: &[BigDigit], b: &mut [BigDigit]) {
105104
);
106105
}
107106

108-
pub(super) fn sub_sign(a: &[BigDigit], b: &[BigDigit]) -> (Sign, BigUint) {
109-
// Normalize:
110-
let a = &a[..a.iter().rposition(|&x| x != 0).map_or(0, |i| i + 1)];
111-
let b = &b[..b.iter().rposition(|&x| x != 0).map_or(0, |i| i + 1)];
112-
113-
match cmp_slice(a, b) {
114-
Greater => {
115-
let mut a = a.to_vec();
116-
sub2(&mut a, b);
117-
(Plus, biguint_from_vec(a))
118-
}
119-
Less => {
120-
let mut b = b.to_vec();
121-
sub2(&mut b, a);
122-
(Minus, biguint_from_vec(b))
123-
}
124-
_ => (NoSign, Zero::zero()),
125-
}
126-
}
127-
128107
forward_val_val_binop!(impl Sub for BigUint, sub);
129108
forward_ref_ref_binop!(impl Sub for BigUint, sub);
130109
forward_val_assign!(impl SubAssign for BigUint, sub_assign);
@@ -331,22 +310,3 @@ impl CheckedSub for BigUint {
331310
}
332311
}
333312
}
334-
335-
#[test]
336-
fn test_sub_sign() {
337-
use crate::BigInt;
338-
use num_traits::Num;
339-
340-
fn sub_sign_i(a: &[BigDigit], b: &[BigDigit]) -> BigInt {
341-
let (sign, val) = sub_sign(a, b);
342-
BigInt::from_biguint(sign, val)
343-
}
344-
345-
let a = BigUint::from_str_radix("265252859812191058636308480000000", 10).unwrap();
346-
let b = BigUint::from_str_radix("26525285981219105863630848000000", 10).unwrap();
347-
let a_i = BigInt::from(a.clone());
348-
let b_i = BigInt::from(b.clone());
349-
350-
assert_eq!(sub_sign_i(&a.data[..], &b.data[..]), &a_i - &b_i);
351-
assert_eq!(sub_sign_i(&b.data[..], &a.data[..]), &b_i - &a_i);
352-
}

0 commit comments

Comments
 (0)