pythonbit-manipulationbitwise-operatorsbit-shiftbitwise-or

bitwise operation set nth bit for negative number


I am trying to set the nth bit of a number by using bitwise operation. I get the nth shifted 1 (n being the index of LSB starting from 0) and then use the OR operation to get set the nth bit. Works fine for positive numbers, and theoretically should work for negative numbers as well because ORing with 0 on the MSB should have no change. But when I run this implementation in Python, I do not get the desired result.

def bitwise_setNthBit(num, n):
  '''
  Check if n th bit is set in the number num or not
  '''
  n_shifted_one = 1<<n
  print(num, bin(num), n_shifted_one, bin(n_shifted_one))
  return num | n_shifted_one

num, n = 10, 2
result = bitwise_setNthBit(num, n)
print('Setting LSB at position {} on {} results in {}'.format(n, num, result))
num, n = -18, 2
result = bitwise_setNthBit(num, n)
print(bin(result))
print('Setting LSB at position {} on {} results in {}'.format(n, num, result))

When using -18 as the number and setting the 2nd bit, I get -18 represented in Binary as -0b10010 and 1<<2 represented i Binary as 0b100. When I do the OR between these numbers, I should get the result as -0b10110 but instead I am getting -0b10010.


Solution

  • I get -18 represented in Binary as -0b10010

    Careful, negative numbers are converted to a binary string in a sneaky way, note the - sign in front: the number really is -0b10010 and not 0b10010. That means the actual bit pattern is the two's complement of the string shown after the minus sign, so ...111101110 (extending infinitely far to the left, just as how for a positive number the zeroes extend infinitely to the left). ORing that with 0b100 doesn't do anything because that bit is already set.