@@ -90,6 +90,7 @@ use std::str::{self, FromStr};
90
90
use std:: fmt;
91
91
#[ cfg( test) ]
92
92
use std:: hash;
93
+ use std:: cmp;
93
94
use std:: cmp:: Ordering :: { self , Less , Greater , Equal } ;
94
95
use std:: { f32, f64} ;
95
96
use std:: { u8, i64, u64} ;
@@ -173,12 +174,7 @@ fn sbb(a: BigDigit, b: BigDigit, borrow: &mut BigDigit) -> BigDigit {
173
174
( * borrow as DoubleBigDigit ) ) ;
174
175
// hi * (base) + lo == 1*(base) + ai - bi - borrow
175
176
// => ai - bi - borrow < 0 <=> hi == 0
176
- //
177
- * borrow = if hi == 0 {
178
- 1
179
- } else {
180
- 0
181
- } ;
177
+ * borrow = ( hi == 0 ) as BigDigit ;
182
178
lo
183
179
}
184
180
@@ -755,20 +751,22 @@ forward_all_binop_to_val_ref_commutative!(impl Add for BigUint, add);
755
751
#[ must_use]
756
752
#[ inline]
757
753
fn __add2 ( a : & mut [ BigDigit ] , b : & [ BigDigit ] ) -> BigDigit {
758
- let mut b_iter = b. iter ( ) ;
754
+ debug_assert ! ( a. len( ) >= b. len( ) ) ;
755
+
759
756
let mut carry = 0 ;
757
+ let ( a_lo, a_hi) = a. split_at_mut ( b. len ( ) ) ;
760
758
761
- for ai in a. iter_mut ( ) {
762
- if let Some ( bi) = b_iter. next ( ) {
763
- * ai = adc ( * ai, * bi, & mut carry) ;
764
- } else if carry != 0 {
765
- * ai = adc ( * ai, 0 , & mut carry) ;
766
- } else {
767
- break ;
759
+ for ( a, b) in a_lo. iter_mut ( ) . zip ( b) {
760
+ * a = adc ( * a, * b, & mut carry) ;
761
+ }
762
+
763
+ if carry != 0 {
764
+ for a in a_hi {
765
+ * a = adc ( * a, 0 , & mut carry) ;
766
+ if carry == 0 { break }
768
767
}
769
768
}
770
769
771
- debug_assert ! ( b_iter. next( ) == None ) ;
772
770
carry
773
771
}
774
772
@@ -832,21 +830,25 @@ impl<'a> Add<&'a BigUint> for BigUint {
832
830
forward_all_binop_to_val_ref ! ( impl Sub for BigUint , sub) ;
833
831
834
832
fn sub2 ( a : & mut [ BigDigit ] , b : & [ BigDigit ] ) {
835
- let mut b_iter = b. iter ( ) ;
836
833
let mut borrow = 0 ;
837
834
838
- for ai in a. iter_mut ( ) {
839
- if let Some ( bi) = b_iter. next ( ) {
840
- * ai = sbb ( * ai, * bi, & mut borrow) ;
841
- } else if borrow != 0 {
842
- * ai = sbb ( * ai, 0 , & mut borrow) ;
843
- } else {
844
- break ;
835
+ let len = cmp:: min ( a. len ( ) , b. len ( ) ) ;
836
+ let ( a_lo, a_hi) = a. split_at_mut ( len) ;
837
+ let ( b_lo, b_hi) = b. split_at ( len) ;
838
+
839
+ for ( a, b) in a_lo. iter_mut ( ) . zip ( b_lo) {
840
+ * a = sbb ( * a, * b, & mut borrow) ;
841
+ }
842
+
843
+ if borrow != 0 {
844
+ for a in a_hi {
845
+ * a = sbb ( * a, 0 , & mut borrow) ;
846
+ if borrow == 0 { break }
845
847
}
846
848
}
847
849
848
850
// note: we're _required_ to fail on underflow
849
- assert ! ( borrow == 0 && b_iter . all( |x| * x == 0 ) ,
851
+ assert ! ( borrow == 0 && b_hi . iter ( ) . all( |x| * x == 0 ) ,
850
852
"Cannot subtract b from a because b is larger than a." ) ;
851
853
}
852
854
@@ -866,14 +868,14 @@ fn sub_sign(a: &[BigDigit], b: &[BigDigit]) -> BigInt {
866
868
867
869
match cmp_slice ( a, b) {
868
870
Greater => {
869
- let mut ret = BigUint :: from_slice ( a ) ;
870
- sub2 ( & mut ret . data [ .. ] , b) ;
871
- BigInt :: from_biguint ( Plus , ret . normalize ( ) )
871
+ let mut a = a . to_vec ( ) ;
872
+ sub2 ( & mut a , b) ;
873
+ BigInt :: new ( Plus , a )
872
874
}
873
875
Less => {
874
- let mut ret = BigUint :: from_slice ( b ) ;
875
- sub2 ( & mut ret . data [ .. ] , a) ;
876
- BigInt :: from_biguint ( Minus , ret . normalize ( ) )
876
+ let mut b = b . to_vec ( ) ;
877
+ sub2 ( & mut b , a) ;
878
+ BigInt :: new ( Minus , b )
877
879
}
878
880
_ => Zero :: zero ( ) ,
879
881
}
0 commit comments