Antonov Mike

Posted on

# Bitwise OR/AND operations

I've always had a poor understanding of bitwise operations. I read two interesting articles and decided to remember how poorly I understand all this stuff. I still don't understand this topic very well, because I don't use it at all, but now I can (if I strain my brain very hard) do this useless nonsense.
The articles:

Bitwise or `|` and bitwise and `&` are operations that compare two numbers bit by bit and return a new number in which each bit is 1 if both corresponding bits in the original numbers are 1 (for bitwise and) or at least one of them is 1 (for bitwise or).
When we perform a bitwise AND operation, we compare each corresponding bit of the two numbers. If both bits are 1, the result bit is 1; otherwise, itβs 0. For example, `3 | 4` equals `7` because `3` is in binary `0011`, `4` is in binary `0100`, and `7` is in binary `0111`. Similarly, `3 & 4` is equal to `0` because no bit is equal to `1` in both numbers.
I wrote an example in Python and Rust. In both examples functions `byte_shift_a` and `byte_shift_b` take one argument `a` and returns the result of the operation `a | b` or `a & b`.

### Rust example

Rust is statically typed and supports closures that can capture their environment, while Python is dynamically typed and uses functions for similar purposes.

``````fn main() {
let b: u8 = 3;

println!("SHIFT A:");
for i in 0..12 {
byte_shift_a(b, i)
}

println!("\nSHIFT B:");
for i in 0..12 {
byte_shift_b(b, i)
}

println!()
}

fn byte_shift_a(b: u8, num: u8) {
let c = |a: u8| a | b;
print!("{}: {}\t", num, c(num))
}

fn byte_shift_b(b: u8, num: u8) {
let c = |a: u8| a & b;
print!("{}: {}\t", num, c(num))
}
``````

### Python example

Python does not have a direct equivalent of Rust's closures, but we can achieve similar functionality using nested functions or lambda functions. This Python code should produce the same output as the original Rust code when executed.

``````def byte_shift_a(b, num):
c = lambda a: a | b
print(f"{num}: {c(num)}\t", end="")

def byte_shift_b(b, num):
c = lambda a: a & b
print(f"{num}: {c(num)}\t", end="")

b = 3

print("SHIFT A:")
for i in range(12):
byte_shift_a(b, i)

print("\nSHIFT B:")
for i in range(12):
byte_shift_b(b, i)

print()
``````

### Both examples will print the same

``````OUTPUT:
SHIFT A:
0: 3    1: 3    2: 3    3: 3    4: 7    5: 7    6: 7    7: 7    8: 11   9: 11   10: 1111: 11
SHIFT B:
0: 0    1: 1    2: 2    3: 3    4: 0    5: 1    6: 2    7: 3    8: 0    9: 1    10: 211: 3
``````

### P.S.

It is also possible to use nested functions within byte_shift_a and byte_shift_b. For example:

``````def byte_shift_a(b, num):
def c(a):
return a | b
print(f"{num}: {c(num)}\t", end="")

def byte_shift_b(b, num):
def c(a):
return a & b
print(f"{num}: {c(num)}\t", end="")
``````