Skip to main content

nanvm_lib/vm/bigint/
bitand.rs

1use core::ops::BitAnd;
2
3use crate::vm::{BigInt, IVm};
4
5impl<A: IVm> BitAnd for BigInt<A> {
6    type Output = Self;
7    fn bitand(self, rhs: Self) -> Self::Output {
8        self.bitwise_op(rhs, |a, b| a & b, |a_neg, b_neg| a_neg && b_neg)
9    }
10}
11
12#[cfg(test)]
13mod tests {
14    use crate::vm::bigint::test_util::{int, neg};
15
16    #[test]
17    fn both_positive() {
18        assert_eq!(int(0b1100) & int(0b1010), int(0b1000));
19    }
20
21    #[test]
22    fn both_negative() {
23        // -1 & -1 == -1 (all-ones AND all-ones).
24        assert_eq!(int(-1) & int(-1), int(-1));
25        // -2 & -3 == -4: 0b...110 & 0b...101 == 0b...100.
26        assert_eq!(int(-2) & int(-3), int(-4));
27    }
28
29    #[test]
30    fn mixed_signs() {
31        // 5 & -1 == 5 (AND with all-ones is identity).
32        assert_eq!(int(5) & int(-1), int(5));
33        // -1 & 5 == 5.
34        assert_eq!(int(-1) & int(5), int(5));
35    }
36
37    #[test]
38    fn with_zero() {
39        assert_eq!(int(0) & int(0), int(0));
40        assert_eq!(int(12_345) & int(0), int(0));
41        assert_eq!(int(-12_345) & int(0), int(0));
42    }
43
44    #[test]
45    fn multi_word_carry_on_decode() {
46        // x = -(0xFFFFFFFF00000001), y = -(0x100000000). Both single-word
47        // magnitudes, so L=1: x's two's-complement word is 0x00000000FFFFFFFF
48        // and y's is 0xFFFFFFFF00000000, which AND to all-zero across that
49        // single word — so decoding the negative result must carry a
50        // brand-new second word into existence, giving -(2^64).
51        let x = neg([0xFFFF_FFFF_0000_0001u64]);
52        let y = neg([0x1_0000_0000u64]);
53        let expected = neg([0u64, 1u64]);
54        assert_eq!(x & y, expected);
55    }
56}