I tried rewriting the small C program below in Python, but I am getting different outputs.
C version:
#include <stdio.h>
int main()
{
  unsigned char data = 0x00;
  unsigned char i;
  unsigned char bit = 0x01;
  unsigned char parity = 1;
  unsigned char value = 0x1c;
  for (i = 0; i < 8; i++)
  {
    data = data | bit;
    bit = bit << 1;
    parity = parity ^ (data & 0x01);
  }
  printf("data: %d bit: %d parity: %d\n", data, bit, parity);
  return 0;
}
Python version:
data = 0
bit = 1
parity = 1
value = int('1c', 16)
for i in range(8):
  data = data | bit
  bit = bit << 1
  parity = parity ^ (data & 1)
print('data: {0} bit: {1} parity: {2}'.format(data, bit, parity))
And the outputs are:
C version
> $ ./test
data: 255 bit: 0 parity: 1
Python version
> $ python3 test.py
data: 255 bit: 256 parity: 1
What am I missing on Python bitwise operations?
As you can see, the only difference in the output is the value of the variable bit.
In your C program, the variable bit is declared as unsigned char. That means it takes on only the values 0 through 255. The last operation on bit in your code is
bit = bit << 1
Before the last time that line is executed, bit is 128. After that line, it "tries" to become 256 but that does not fit into an unsigned char. So overflow happens, not flagged by your program, and bit becomes 0.
In the Python program, the variable bit is simply an integer, int, which has no maximum size. So there is no overflow, and bit does become 256.
There are several ways to overcome that difference in Python.  You could force bit to stay in the desired range by instead using
bit = (bit << 1) % 256
or perhaps
bit = (bit << 1) & 255
You could instead make bit to be the equivalent of an unsigned char variable. As a comment says, you could use the ctypes module, I believe. You could also use numpy (I'm more familiar with that).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With