@@ -21,6 +21,7 @@ use Integer;
2121use std:: cmp;
2222use std:: fmt;
2323use std:: from_str:: FromStr ;
24+ use std:: num:: CheckedDiv ;
2425use std:: num:: { Bitwise , ToPrimitive , FromPrimitive } ;
2526use std:: num:: { Zero , One , ToStrRadix , FromStrRadix } ;
2627use std:: rand:: Rng ;
@@ -338,6 +339,40 @@ impl Neg<BigUint> for BigUint {
338339 fn neg ( & self ) -> BigUint { fail ! ( ) }
339340}
340341
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+
341376impl Integer for BigUint {
342377 #[ inline]
343378 fn div_rem ( & self , other : & BigUint ) -> ( BigUint , BigUint ) {
@@ -1053,6 +1088,38 @@ impl Neg<BigInt> for BigInt {
10531088 }
10541089}
10551090
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+
10561123impl Integer for BigInt {
10571124 #[ inline]
10581125 fn div_rem ( & self , other : & BigInt ) -> ( BigInt , BigInt ) {
@@ -1402,6 +1469,7 @@ mod biguint_tests {
14021469 use std::i64;
14031470 use std::num::{Zero, One, FromStrRadix, ToStrRadix};
14041471 use std::num::{ToPrimitive, FromPrimitive};
1472+ use std::num::CheckedDiv;
14051473 use std::rand::{task_rng};
14061474 use std::str;
14071475 use std::u64;
@@ -1822,6 +1890,82 @@ mod biguint_tests {
18221890 }
18231891 }
18241892
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+
18251969 #[ test]
18261970 fn test_gcd ( ) {
18271971 fn check ( a : uint , b : uint , c : uint ) {
@@ -2058,6 +2202,7 @@ mod bigint_tests {
20582202
20592203 use std:: cmp:: { Less , Equal , Greater } ;
20602204 use std:: i64;
2205+ use std:: num:: CheckedDiv ;
20612206 use std:: num:: { Zero , One , FromStrRadix , ToStrRadix } ;
20622207 use std:: num:: { ToPrimitive , FromPrimitive } ;
20632208 use std:: rand:: { task_rng} ;
@@ -2399,6 +2544,94 @@ mod bigint_tests {
23992544 }
24002545 }
24012546
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+
24022635 #[ test]
24032636 fn test_gcd ( ) {
24042637 fn check ( a : int , b : int , c : int ) {
0 commit comments