Skip to content
Advertisement

Does a bitwise “and” operation prepend zeros to the binary representation?

When I use bitwise and operator(&) with the number of 1 to find out if a number x is odd or even (x & 1), does the interpreter change the binary representation of 1 according to the binary representation of x? For example:

  • 2 & 1 -> 10 & 01 -> then perform comparison bitwise
  • 5 & 1 -> 101 & 001 -> then perform comparison bitwise
  • 100 & 1 -> 1100100 & 0000001 -> then perform comparison bitwise

Does it append zeros to the binary representation of 1 to perform bitwise and operation?

Looking at the cpython implementation, it looks like that it compares the digits according to size of the right argument. So in this case the example above works actually:

  • 2 & 1 -> 10 & 1 -> 0 & 1 -> then perform comparison bitwise
  • 5 & 1 -> 101 & 1 -> 1 & 1 -> then perform comparison bitwise
  • 100 & 1 -> 1100100 & 1 -> 0 & 1 -> then perform comparison bitwise

Is my understanding right? I’m confused because of this image from Geeks for Geeks.

Advertisement

Answer

Conceptually, adding zeros to the shorter number gives the same result as ignoring excess digits in the longer number. They both do the same thing. Padding, however, is inefficient, so in practice you wouldn’t want to do it.

The reason is because anything ANDed with 0 is 0. If you pad the short number to match the longer one and then AND the extra bits they’re all going to result in 0. It works, but since you know the padded bits will just result in extra zeros, it’s more efficient to ignore them and only iterate over the length of the shorter number.

Python only processes the overlapping digits. First, it conditionally swaps a and b to ensure b is the smaller number:

/* Swap a and b if necessary to ensure size_a >= size_b. */
if (size_a < size_b) {
    z = a; a = b; b = z;
    size_z = size_a; size_a = size_b; size_b = size_z;
    negz = nega; nega = negb; negb = negz;
}

Then it iterates over the smaller size_b:

/* Compute digits for overlap of a and b. */
switch(op) {
case '&':
    for (i = 0; i < size_b; ++i)
        z->ob_digit[i] = a->ob_digit[i] & b->ob_digit[i];
    break;

So my understanding is right, the image is just for intuition?

Yep, correct. The image is for conceptual understanding. It doesn’t reflect how it’s actually implemented in code.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement