Search code examples
pythonpython-3.xbit-manipulationbit

How to modify multiple bits in an integer?


Challenge:

I would like to write a method which would take

  1. INTEGER value
  2. START_BIT
  3. Number of bits to be replaced after the START_BIT
  4. REPLACING_BIT (boolean)

Return: the modified value based on the inputs.

Input Example:

  • Decimal: 255 or in Binary: 11111111

Expected output:

  • Decimal: 227 or in Binary: 11100011

i.e 3 bits are replaced with ZEROS starting from second bit position.

Current code:

def set_bit(original_int:int, start_bit_pos:int, number_of_bits:int, bit_value:bool):
    if number_of_bits < 1: number_of_bits = 1
        
    out = original_int
    for i in range(number_of_bits):
        if bit_value == 1:
            out = out | (1<<(start_bit_pos+i))
        else:
            out = out & ~(1<<(start_bit_pos+i))
    print('old binary: '+ '{:b}'.format(original_int),f' Decimal: {original_int}' )
    print('new binary: '+ '{:b}'.format(out), f' Decimal: {out}' )
    return out

set_bit(original_int = 255, start_bit_pos= 2, number_of_bits = 3, bit_value = 0)
set_bit(original_int = 64, start_bit_pos= 2, number_of_bits = 3, bit_value = 1)

Current issue:

The above code is functional, however I do feel it is an overkill, so I wonder if there is a standard python function which could do a similar thing?


Solution

    • A sequence of 1 bits is 1.
    • A sequence of 2 bits is 11 or decimal 3.
    • A sequence of 3 bits is 111 or decimal 7.
    • A sequence of N bits is 2^N-1, which is the same as (1 << N) - 1.

    You have to also shift that to the left if the starting position is not 0.

    Therefore, you can simply do this:

    def set_bit(original_int:int, start_bit_pos:int,
                number_of_bits:int, bit_value:bool):
        mask = (1 << number_of_bits) - 1 << start_bit_pos
        if bit_value:
            return original_int | mask
        return original_int & ~mask