diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index cb76422815530..a9574f4103bb3 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -153,6 +153,43 @@ impl Orderable for BigUint { } } +impl BitAnd 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 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 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 for BigUint { #[inline] fn shl(&self, rhs: &uint) -> BigUint { @@ -1166,6 +1203,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) {