@@ -21,6 +21,7 @@ use Integer;
21
21
use std:: cmp;
22
22
use std:: fmt;
23
23
use std:: from_str:: FromStr ;
24
+ use std:: num:: CheckedDiv ;
24
25
use std:: num:: { Bitwise , ToPrimitive , FromPrimitive } ;
25
26
use std:: num:: { Zero , One , ToStrRadix , FromStrRadix } ;
26
27
use std:: rand:: Rng ;
@@ -338,6 +339,40 @@ impl Neg<BigUint> for BigUint {
338
339
fn neg ( & self ) -> BigUint { fail ! ( ) }
339
340
}
340
341
342
+ impl CheckedAdd for BigUint {
343
+ #[ inline]
344
+ fn checked_add ( & self , v : & BigUint ) -> Option < BigUint > {
345
+ return Some ( self . add ( v) ) ;
346
+ }
347
+ }
348
+
349
+ impl CheckedSub for BigUint {
350
+ #[ inline]
351
+ fn checked_sub ( & self , v : & BigUint ) -> Option < BigUint > {
352
+ if * self < * v {
353
+ return None ;
354
+ }
355
+ return Some ( self . sub ( v) ) ;
356
+ }
357
+ }
358
+
359
+ impl CheckedMul for BigUint {
360
+ #[ inline]
361
+ fn checked_mul ( & self , v : & BigUint ) -> Option < BigUint > {
362
+ return Some ( self . mul ( v) ) ;
363
+ }
364
+ }
365
+
366
+ impl CheckedDiv for BigUint {
367
+ #[ inline]
368
+ fn checked_div ( & self , v : & BigUint ) -> Option < BigUint > {
369
+ if v. is_zero ( ) {
370
+ return None ;
371
+ }
372
+ return Some ( self . div ( v) ) ;
373
+ }
374
+ }
375
+
341
376
impl Integer for BigUint {
342
377
#[ inline]
343
378
fn div_rem ( & self , other : & BigUint ) -> ( BigUint , BigUint ) {
@@ -1053,6 +1088,38 @@ impl Neg<BigInt> for BigInt {
1053
1088
}
1054
1089
}
1055
1090
1091
+ impl CheckedAdd for BigInt {
1092
+ #[ inline]
1093
+ fn checked_add ( & self , v : & BigInt ) -> Option < BigInt > {
1094
+ return Some ( self . add ( v) ) ;
1095
+ }
1096
+ }
1097
+
1098
+ impl CheckedSub for BigInt {
1099
+ #[ inline]
1100
+ fn checked_sub ( & self , v : & BigInt ) -> Option < BigInt > {
1101
+ return Some ( self . sub ( v) ) ;
1102
+ }
1103
+ }
1104
+
1105
+ impl CheckedMul for BigInt {
1106
+ #[ inline]
1107
+ fn checked_mul ( & self , v : & BigInt ) -> Option < BigInt > {
1108
+ return Some ( self . mul ( v) ) ;
1109
+ }
1110
+ }
1111
+
1112
+ impl CheckedDiv for BigInt {
1113
+ #[ inline]
1114
+ fn checked_div ( & self , v : & BigInt ) -> Option < BigInt > {
1115
+ if v. is_zero ( ) {
1116
+ return None ;
1117
+ }
1118
+ return Some ( self . div ( v) ) ;
1119
+ }
1120
+ }
1121
+
1122
+
1056
1123
impl Integer for BigInt {
1057
1124
#[ inline]
1058
1125
fn div_rem ( & self , other : & BigInt ) -> ( BigInt , BigInt ) {
@@ -1402,6 +1469,7 @@ mod biguint_tests {
1402
1469
use std::i64;
1403
1470
use std::num::{Zero, One, FromStrRadix, ToStrRadix};
1404
1471
use std::num::{ToPrimitive, FromPrimitive};
1472
+ use std::num::CheckedDiv;
1405
1473
use std::rand::{task_rng};
1406
1474
use std::str;
1407
1475
use std::u64;
@@ -1822,6 +1890,82 @@ mod biguint_tests {
1822
1890
}
1823
1891
}
1824
1892
1893
+ #[ test]
1894
+ fn test_checked_add ( ) {
1895
+ for elm in sum_triples. iter ( ) {
1896
+ let ( aVec, bVec, cVec) = * elm;
1897
+ let a = BigUint :: from_slice ( aVec) ;
1898
+ let b = BigUint :: from_slice ( bVec) ;
1899
+ let c = BigUint :: from_slice ( cVec) ;
1900
+
1901
+ assert ! ( a. checked_add( & b) . unwrap( ) == c) ;
1902
+ assert ! ( b. checked_add( & a) . unwrap( ) == c) ;
1903
+ }
1904
+ }
1905
+
1906
+ #[ test]
1907
+ fn test_checked_sub ( ) {
1908
+ for elm in sum_triples. iter ( ) {
1909
+ let ( aVec, bVec, cVec) = * elm;
1910
+ let a = BigUint :: from_slice ( aVec) ;
1911
+ let b = BigUint :: from_slice ( bVec) ;
1912
+ let c = BigUint :: from_slice ( cVec) ;
1913
+
1914
+ assert ! ( c. checked_sub( & a) . unwrap( ) == b) ;
1915
+ assert ! ( c. checked_sub( & b) . unwrap( ) == a) ;
1916
+
1917
+ if a > c {
1918
+ assert ! ( a. checked_sub( & c) . is_none( ) ) ;
1919
+ }
1920
+ if b > c {
1921
+ assert ! ( b. checked_sub( & c) . is_none( ) ) ;
1922
+ }
1923
+ }
1924
+ }
1925
+
1926
+ #[ test]
1927
+ fn test_checked_mul ( ) {
1928
+ for elm in mul_triples. iter ( ) {
1929
+ let ( aVec, bVec, cVec) = * elm;
1930
+ let a = BigUint :: from_slice ( aVec) ;
1931
+ let b = BigUint :: from_slice ( bVec) ;
1932
+ let c = BigUint :: from_slice ( cVec) ;
1933
+
1934
+ assert ! ( a. checked_mul( & b) . unwrap( ) == c) ;
1935
+ assert ! ( b. checked_mul( & a) . unwrap( ) == c) ;
1936
+ }
1937
+
1938
+ for elm in div_rem_quadruples. iter ( ) {
1939
+ let ( aVec, bVec, cVec, dVec) = * elm;
1940
+ let a = BigUint :: from_slice ( aVec) ;
1941
+ let b = BigUint :: from_slice ( bVec) ;
1942
+ let c = BigUint :: from_slice ( cVec) ;
1943
+ let d = BigUint :: from_slice ( dVec) ;
1944
+
1945
+ assert ! ( a == b. checked_mul( & c) . unwrap( ) + d) ;
1946
+ assert ! ( a == c. checked_mul( & b) . unwrap( ) + d) ;
1947
+ }
1948
+ }
1949
+
1950
+ #[ test]
1951
+ fn test_checked_div ( ) {
1952
+ for elm in mul_triples. iter ( ) {
1953
+ let ( aVec, bVec, cVec) = * elm;
1954
+ let a = BigUint :: from_slice ( aVec) ;
1955
+ let b = BigUint :: from_slice ( bVec) ;
1956
+ let c = BigUint :: from_slice ( cVec) ;
1957
+
1958
+ if !a. is_zero ( ) {
1959
+ assert ! ( c. checked_div( & a) . unwrap( ) == b) ;
1960
+ }
1961
+ if !b. is_zero ( ) {
1962
+ assert ! ( c. checked_div( & b) . unwrap( ) == a) ;
1963
+ }
1964
+
1965
+ assert ! ( c. checked_div( & Zero :: zero( ) ) . is_none( ) ) ;
1966
+ }
1967
+ }
1968
+
1825
1969
#[ test]
1826
1970
fn test_gcd ( ) {
1827
1971
fn check ( a : uint , b : uint , c : uint ) {
@@ -2058,6 +2202,7 @@ mod bigint_tests {
2058
2202
2059
2203
use std:: cmp:: { Less , Equal , Greater } ;
2060
2204
use std:: i64;
2205
+ use std:: num:: CheckedDiv ;
2061
2206
use std:: num:: { Zero , One , FromStrRadix , ToStrRadix } ;
2062
2207
use std:: num:: { ToPrimitive , FromPrimitive } ;
2063
2208
use std:: rand:: { task_rng} ;
@@ -2399,6 +2544,94 @@ mod bigint_tests {
2399
2544
}
2400
2545
}
2401
2546
2547
+ #[ test]
2548
+ fn test_checked_add ( ) {
2549
+ for elm in sum_triples. iter ( ) {
2550
+ let ( aVec, bVec, cVec) = * elm;
2551
+ let a = BigInt :: from_slice ( Plus , aVec) ;
2552
+ let b = BigInt :: from_slice ( Plus , bVec) ;
2553
+ let c = BigInt :: from_slice ( Plus , cVec) ;
2554
+
2555
+ assert ! ( a. checked_add( & b) . unwrap( ) == c) ;
2556
+ assert ! ( b. checked_add( & a) . unwrap( ) == c) ;
2557
+ assert ! ( c. checked_add( & ( -a) ) . unwrap( ) == b) ;
2558
+ assert ! ( c. checked_add( & ( -b) ) . unwrap( ) == a) ;
2559
+ assert ! ( a. checked_add( & ( -c) ) . unwrap( ) == ( -b) ) ;
2560
+ assert ! ( b. checked_add( & ( -c) ) . unwrap( ) == ( -a) ) ;
2561
+ assert ! ( ( -a) . checked_add( & ( -b) ) . unwrap( ) == ( -c) )
2562
+ assert ! ( a. checked_add( & ( -a) ) . unwrap( ) == Zero :: zero( ) ) ;
2563
+ }
2564
+ }
2565
+
2566
+ #[ test]
2567
+ fn test_checked_sub ( ) {
2568
+ for elm in sum_triples. iter ( ) {
2569
+ let ( aVec, bVec, cVec) = * elm;
2570
+ let a = BigInt :: from_slice ( Plus , aVec) ;
2571
+ let b = BigInt :: from_slice ( Plus , bVec) ;
2572
+ let c = BigInt :: from_slice ( Plus , cVec) ;
2573
+
2574
+ assert ! ( c. checked_sub( & a) . unwrap( ) == b) ;
2575
+ assert ! ( c. checked_sub( & b) . unwrap( ) == a) ;
2576
+ assert ! ( ( -b) . checked_sub( & a) . unwrap( ) == ( -c) )
2577
+ assert ! ( ( -a) . checked_sub( & b) . unwrap( ) == ( -c) )
2578
+ assert ! ( b. checked_sub( & ( -a) ) . unwrap( ) == c) ;
2579
+ assert ! ( a. checked_sub( & ( -b) ) . unwrap( ) == c) ;
2580
+ assert ! ( ( -c) . checked_sub( & ( -a) ) . unwrap( ) == ( -b) ) ;
2581
+ assert ! ( a. checked_sub( & a) . unwrap( ) == Zero :: zero( ) ) ;
2582
+ }
2583
+ }
2584
+
2585
+ #[ test]
2586
+ fn test_checked_mul ( ) {
2587
+ for elm in mul_triples. iter ( ) {
2588
+ let ( aVec, bVec, cVec) = * elm;
2589
+ let a = BigInt :: from_slice ( Plus , aVec) ;
2590
+ let b = BigInt :: from_slice ( Plus , bVec) ;
2591
+ let c = BigInt :: from_slice ( Plus , cVec) ;
2592
+
2593
+ assert ! ( a. checked_mul( & b) . unwrap( ) == c) ;
2594
+ assert ! ( b. checked_mul( & a) . unwrap( ) == c) ;
2595
+
2596
+ assert ! ( ( -a) . checked_mul( & b) . unwrap( ) == -c) ;
2597
+ assert ! ( ( -b) . checked_mul( & a) . unwrap( ) == -c) ;
2598
+ }
2599
+
2600
+ for elm in div_rem_quadruples. iter ( ) {
2601
+ let ( aVec, bVec, cVec, dVec) = * elm;
2602
+ let a = BigInt :: from_slice ( Plus , aVec) ;
2603
+ let b = BigInt :: from_slice ( Plus , bVec) ;
2604
+ let c = BigInt :: from_slice ( Plus , cVec) ;
2605
+ let d = BigInt :: from_slice ( Plus , dVec) ;
2606
+
2607
+ assert ! ( a == b. checked_mul( & c) . unwrap( ) + d) ;
2608
+ assert ! ( a == c. checked_mul( & b) . unwrap( ) + d) ;
2609
+ }
2610
+ }
2611
+ #[ test]
2612
+ fn test_checked_div ( ) {
2613
+ for elm in mul_triples. iter ( ) {
2614
+ let ( aVec, bVec, cVec) = * elm;
2615
+ let a = BigInt :: from_slice ( Plus , aVec) ;
2616
+ let b = BigInt :: from_slice ( Plus , bVec) ;
2617
+ let c = BigInt :: from_slice ( Plus , cVec) ;
2618
+
2619
+ if !a. is_zero ( ) {
2620
+ assert ! ( c. checked_div( & a) . unwrap( ) == b) ;
2621
+ assert ! ( ( -c) . checked_div( & ( -a) ) . unwrap( ) == b) ;
2622
+ assert ! ( ( -c) . checked_div( & a) . unwrap( ) == -b) ;
2623
+ }
2624
+ if !b. is_zero ( ) {
2625
+ assert ! ( c. checked_div( & b) . unwrap( ) == a) ;
2626
+ assert ! ( ( -c) . checked_div( & ( -b) ) . unwrap( ) == a) ;
2627
+ assert ! ( ( -c) . checked_div( & b) . unwrap( ) == -a) ;
2628
+ }
2629
+
2630
+ assert ! ( c. checked_div( & Zero :: zero( ) ) . is_none( ) ) ;
2631
+ assert ! ( ( -c) . checked_div( & Zero :: zero( ) ) . is_none( ) ) ;
2632
+ }
2633
+ }
2634
+
2402
2635
#[ test]
2403
2636
fn test_gcd ( ) {
2404
2637
fn check ( a : int , b : int , c : int ) {
0 commit comments