@@ -21,6 +21,9 @@ pub mod big_digit {
21
21
/// size is the double of the size of `BigDigit`.
22
22
pub type DoubleBigDigit = u64 ;
23
23
24
+ /// A `SignedDoubleBigDigit` is the signed version of `DoubleBigDigit`.
25
+ pub type SignedDoubleBigDigit = i64 ;
26
+
24
27
pub const ZERO_BIG_DIGIT : BigDigit = 0 ;
25
28
26
29
// `DoubleBigDigit` size dependent
@@ -51,47 +54,44 @@ pub mod big_digit {
51
54
}
52
55
}
53
56
54
- use big_digit:: { BigDigit , DoubleBigDigit } ;
57
+ use big_digit:: { BigDigit , DoubleBigDigit , SignedDoubleBigDigit } ;
55
58
56
59
// Generic functions for add/subtract/multiply with carry/borrow:
57
60
58
61
// Add with carry:
59
62
#[ inline]
60
- fn adc ( a : BigDigit , b : BigDigit , carry : & mut BigDigit ) -> BigDigit {
61
- let ( hi , lo ) = big_digit :: from_doublebigdigit ( ( a as DoubleBigDigit ) + ( b as DoubleBigDigit ) +
62
- ( * carry as DoubleBigDigit ) ) ;
63
-
64
- * carry = hi ;
63
+ fn adc ( a : BigDigit , b : BigDigit , acc : & mut DoubleBigDigit ) -> BigDigit {
64
+ * acc += a as DoubleBigDigit ;
65
+ * acc += b as DoubleBigDigit ;
66
+ let lo = * acc as BigDigit ;
67
+ * acc >>= big_digit :: BITS ;
65
68
lo
66
69
}
67
70
68
71
// Subtract with borrow:
69
72
#[ inline]
70
- fn sbb ( a : BigDigit , b : BigDigit , borrow : & mut BigDigit ) -> BigDigit {
71
- let ( hi, lo) = big_digit:: from_doublebigdigit ( big_digit:: BASE + ( a as DoubleBigDigit ) -
72
- ( b as DoubleBigDigit ) -
73
- ( * borrow as DoubleBigDigit ) ) ;
74
- // hi * (base) + lo == 1*(base) + ai - bi - borrow
75
- // => ai - bi - borrow < 0 <=> hi == 0
76
- * borrow = ( hi == 0 ) as BigDigit ;
73
+ fn sbb ( a : BigDigit , b : BigDigit , acc : & mut SignedDoubleBigDigit ) -> BigDigit {
74
+ * acc += a as SignedDoubleBigDigit ;
75
+ * acc -= b as SignedDoubleBigDigit ;
76
+ let lo = * acc as BigDigit ;
77
+ * acc >>= big_digit:: BITS ;
77
78
lo
78
79
}
79
80
80
81
#[ inline]
81
- pub fn mac_with_carry ( a : BigDigit , b : BigDigit , c : BigDigit , carry : & mut BigDigit ) -> BigDigit {
82
- let ( hi , lo ) = big_digit :: from_doublebigdigit ( ( a as DoubleBigDigit ) +
83
- ( b as DoubleBigDigit ) * ( c as DoubleBigDigit ) +
84
- ( * carry as DoubleBigDigit ) ) ;
85
- * carry = hi ;
82
+ pub fn mac_with_carry ( a : BigDigit , b : BigDigit , c : BigDigit , acc : & mut DoubleBigDigit ) -> BigDigit {
83
+ * acc += a as DoubleBigDigit ;
84
+ * acc += ( b as DoubleBigDigit ) * ( c as DoubleBigDigit ) ;
85
+ let lo = * acc as BigDigit ;
86
+ * acc >>= big_digit :: BITS ;
86
87
lo
87
88
}
88
89
89
90
#[ inline]
90
- pub fn mul_with_carry ( a : BigDigit , b : BigDigit , carry : & mut BigDigit ) -> BigDigit {
91
- let ( hi, lo) = big_digit:: from_doublebigdigit ( ( a as DoubleBigDigit ) * ( b as DoubleBigDigit ) +
92
- ( * carry as DoubleBigDigit ) ) ;
93
-
94
- * carry = hi;
91
+ pub fn mul_with_carry ( a : BigDigit , b : BigDigit , acc : & mut DoubleBigDigit ) -> BigDigit {
92
+ * acc += ( a as DoubleBigDigit ) * ( b as DoubleBigDigit ) ;
93
+ let lo = * acc as BigDigit ;
94
+ * acc >>= big_digit:: BITS ;
95
95
lo
96
96
}
97
97
@@ -141,7 +141,7 @@ pub fn __add2(a: &mut [BigDigit], b: &[BigDigit]) -> BigDigit {
141
141
}
142
142
}
143
143
144
- carry
144
+ carry as BigDigit
145
145
}
146
146
147
147
/// /Two argument addition of raw slices:
@@ -446,7 +446,7 @@ pub fn scalar_mul(a: &mut [BigDigit], b: BigDigit) -> BigDigit {
446
446
for a in a. iter_mut ( ) {
447
447
* a = mul_with_carry ( * a, b, & mut carry) ;
448
448
}
449
- carry
449
+ carry as BigDigit
450
450
}
451
451
452
452
pub fn div_rem ( u : & BigUint , d : & BigUint ) -> ( BigUint , BigUint ) {
0 commit comments