diff options
| author | David Creswick <dcrewi@gyrae.net> | 2013-09-06 20:47:54 -0500 |
|---|---|---|
| committer | David Creswick <dcrewi@gyrae.net> | 2013-09-09 12:15:19 -0500 |
| commit | c3d0fc23d4980f9408656c61bd71049f1bd56849 (patch) | |
| tree | 38433bf8c76743a8d3050890d48c5d4426ea61b2 | |
| parent | d84a7b5ae3b3a820fb0a26292632856ceb959b3e (diff) | |
| download | rust-c3d0fc23d4980f9408656c61bd71049f1bd56849.tar.gz rust-c3d0fc23d4980f9408656c61bd71049f1bd56849.zip | |
Implement bitwise operations on BigUint
| -rw-r--r-- | src/libextra/num/bigint.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index cb764228155..a9574f4103b 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -153,6 +153,43 @@ impl Orderable for BigUint { } } +impl BitAnd<BigUint, BigUint> for BigUint { + fn bitand(&self, other: &BigUint) -> BigUint { + let new_len = num::min(self.data.len(), other.data.len()); + let anded = do vec::from_fn(new_len) |i| { + // i will never be less than the size of either data vector + let ai = self.data[i]; + let bi = other.data[i]; + ai & bi + }; + return BigUint::new(anded); + } +} + +impl BitOr<BigUint, BigUint> for BigUint { + fn bitor(&self, other: &BigUint) -> BigUint { + let new_len = num::max(self.data.len(), other.data.len()); + let ored = do vec::from_fn(new_len) |i| { + let ai = if i < self.data.len() { self.data[i] } else { 0 }; + let bi = if i < other.data.len() { other.data[i] } else { 0 }; + ai | bi + }; + return BigUint::new(ored); + } +} + +impl BitXor<BigUint, BigUint> for BigUint { + fn bitxor(&self, other: &BigUint) -> BigUint { + let new_len = num::max(self.data.len(), other.data.len()); + let xored = do vec::from_fn(new_len) |i| { + let ai = if i < self.data.len() { self.data[i] } else { 0 }; + let bi = if i < other.data.len() { other.data[i] } else { 0 }; + ai ^ bi + }; + return BigUint::new(xored); + } +} + impl Shl<uint, BigUint> for BigUint { #[inline] fn shl(&self, rhs: &uint) -> BigUint { @@ -1167,6 +1204,48 @@ mod biguint_tests { } #[test] + fn test_bitand() { + fn check(left: ~[BigDigit], + right: ~[BigDigit], + expected: ~[BigDigit]) { + assert_eq!(BigUint::new(left) & BigUint::new(right), + BigUint::new(expected)); + } + check(~[], ~[], ~[]); + check(~[268, 482, 17], + ~[964, 54], + ~[260, 34]); + } + + #[test] + fn test_bitor() { + fn check(left: ~[BigDigit], + right: ~[BigDigit], + expected: ~[BigDigit]) { + assert_eq!(BigUint::new(left) | BigUint::new(right), + BigUint::new(expected)); + } + check(~[], ~[], ~[]); + check(~[268, 482, 17], + ~[964, 54], + ~[972, 502, 17]); + } + + #[test] + fn test_bitxor() { + fn check(left: ~[BigDigit], + right: ~[BigDigit], + expected: ~[BigDigit]) { + assert_eq!(BigUint::new(left) ^ BigUint::new(right), + BigUint::new(expected)); + } + check(~[], ~[], ~[]); + check(~[268, 482, 17], + ~[964, 54], + ~[712, 468, 17]); + } + + #[test] fn test_shl() { fn check(s: &str, shift: uint, ans: &str) { let opt_biguint: Option<BigUint> = FromStrRadix::from_str_radix(s, 16); |
