How to modify bits in an integer?

前端 未结 4 2269
暖寄归人
暖寄归人 2020-12-08 21:01

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

相关标签:
4条回答
  • 2020-12-08 21:35

    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.

    0 讨论(0)
  • 2020-12-08 21:37

    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.

    0 讨论(0)
  • 2020-12-08 21:55

    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).

    0 讨论(0)
  • 2020-12-08 22:01

    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'
    
    0 讨论(0)
提交回复
热议问题