about summary refs log tree commit diff
path: root/src/libextra
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-09-09 14:10:58 -0700
committerbors <bors@rust-lang.org>2013-09-09 14:10:58 -0700
commited695d470bf1568b896f2944815f4723905ab66e (patch)
tree0658baf3f939baac9aa55727862c66188939b68d /src/libextra
parent54ae2800ffb30513f89ce13d27ac3c8d095d98ac (diff)
parentc3d0fc23d4980f9408656c61bd71049f1bd56849 (diff)
downloadrust-ed695d470bf1568b896f2944815f4723905ab66e.tar.gz
rust-ed695d470bf1568b896f2944815f4723905ab66e.zip
auto merge of #9083 : dcrewi/rust/biguint-bit-ops, r=brson
Diffstat (limited to 'src/libextra')
-rw-r--r--src/libextra/num/bigint.rs79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs
index 2e61b7fdbdc..e9b267e9588 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);