0

Now, I know the way to set the i'th bit of a number is use the shift operator to shift 1 till you reach the required bit, and then just or it with the number. But this process is O(length of number) because shifting a number to the i'th position is like traversing until there, right? Please correct me if I'm wrong.

Here is my code:

x = x| (1<<i)

Is there a way to do this in O(1)? In other words, how does one get direct access to the bits in a number? I'm thinking along the lines of array indexing.

Mahathi Vempati
  • 1,238
  • 1
  • 12
  • 33

2 Answers2

5

Shifting 1 by k bits is done in hardware. At a grossly simplified level, an n-bit CPU has n registers that represent a number shifted by 0, 1, 2, ..., n-1 bits in each direction. When a shift operation is executed, CPU loads the number in a register k based on the number of shifts, and reads the output in the next cycle. This makes bit shifting an O(1) operation.

This Q&A has a diagram explaining the hardware behind the O(1) "magic" of modern CPUs using multiplexers.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
2

As others have pointed out n |= 1 << i is not O(n). This is because a bit shift operation in most CPU's is a single instruction, on the ones I am familiar with at the moment it takes a cycle or two IIRC.

If however, you are introducing a loop within your C code, then this of course, will be O(n), such as:

n = 1;
for(j = 0; j < i; ++j)
    n <<= 1;
x |= n;

For a refactored bit setting for generically setting a bit in an integer value, you could do something like:

typedef enum x_bits_e {
    x_bit1 = 1 << 0;
    x_bit2 = 1 << 1;
    x_bit3 = 1 << 2; 
     // and so on
};

int16_t set_bit_in_x(int16 x, x_bits_e i)
{ 
    return x | i;
}
Toby
  • 9,696
  • 16
  • 68
  • 132