简体   繁体   中英

How to modify bits in an integer?

I have an integer with a value 7 ( 0b00000111 ) And I would like to replace it with a function to 13 ( 0b00001101 ). What is the best algorithm to replace bits in an integer?

For example:

set_bits(somevalue, 3, 1) # What makes the 3rd bit to 1 in somevalue?

These work for integers of any size, even greater than 32 bit:

def set_bit(value, bit):
    return value | (1<<bit)

def clear_bit(value, bit):
    return value & ~(1<<bit)

If you like things short, you can just use:

>>> val = 0b111
>>> val |= (1<<3)
>>> '{:b}'.format(val)
'1111'
>>> val &=~ (1<<1)
'1101'

You just need:

def set_bit(v, index, x):
  """Set the index:th bit of v to 1 if x is truthy, else to 0, and return the new value."""
  mask = 1 << index   # Compute mask, an integer with just bit 'index' set.
  v &= ~mask          # Clear the bit indicated by the mask (if x is False)
  if x:
    v |= mask         # If x was True, set the bit indicated by the mask.
  return v            # Return the result, we're done.

>>> set_bit(7, 3, 1)
15
>>> set_bit(set_bit(7, 1, 0), 3, 1)
13

Note that bit numbers ( index ) are from 0, with 0 being the least significant bit.

Also note that the new value is returned , there's no way to modify an integer "in place" like you show (at least I don't think so).

You can use bitwise opertions. http://wiki.python.org/moin/BitwiseOperators

if you want to set a given bit to 1 you can use bitwise 'or' with 1 on given position:

0b00000111 | 0b00001000 = 0b00001111

to set a given bit to 0 you can use bitwise 'and'

0b00001111 & 0b11111011 = 0b00001011

Note that 0b prefix is for binary numbers and 0x is for hexadecimal.

I was pointed here by site admins...

Im still a bit confused how I can use the above function to set the appropriate bit pattern

I also might want to change the byte at runtime but on 1 bit at a time....ie just turn off TEI (TEI = False)

Thoughts?

mask = 0b00000000

TEI = True
TRANSPORT_PRIORITY = False

if TEI == True:
    mask = 0b10000000 | mask
elif TEI == False:
    mask = 0b01111111 & mask

if TRANSPORT_PRIORITY == True:
    mask = 0b01000000 | mask
elif TRANSPORT_PRIORITY == False:
    mask = 0b10111111 & mask


print(bin(mask))
print(hex(mask))

Thanks in advance

Neil

Going by the examples provided, it sounds like you are looking to swap bits in an integer. For example in 7 (0b00000111) , if you swap the bits in the 3rd and 1st positions you obtain 13 (0b00001101) .

I would have the following as a function signature swap_bits(val, i, j)

What is the best algorithm? Well, the following algorithm takes constant time, O(1).

def swap_bits(val, i, j):
    """
    Given an integer val, swap bits in positions i and j if they differ
    by flipping their values, i.e, select the bits to flip with a mask.
    Since v ^ 1 = 0 when v = 1 and 1 when v = 0, perform the flip using an XOR.
    """
    if not (val >> i) & 1 == (val >> j) & 1:
        mask = (1 << i) | (1 << j)
        val ^= mask
    return val

Example:

 >>> swap_bits(7, 3, 1)
 13

The code leverage bit twiddling tricks and here is a good resource by Sean Anderson. I am working on providing the code snippets in Python here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM