Set Multiple Bits in 8-bit Register

Code

#include <stdio.h>
#include <stdint.h>

uint8_t set_range(uint8_t reg, uint8_t start, uint8_t end) 
{
    uint16_t set_val = (((1 << (end + 1)) - 1) >> start) << start;
    reg |= (uint8_t)set_val;
    return reg;
}

int main() {
    uint8_t reg, start, end;
    scanf("%hhu %hhu %hhu", &reg, &start, &end);
    printf("%u", set_range(reg, start, end));
    return 0;
}

Solving Approach

This code is a bitwise utility designed to set a contiguous range of bits (turn them into 1s) within an 8-bit register without affecting the other bits.

The Core Logic: Mask Generation

The most interesting part of this code is how it creates a "mask" to identify which bits to flip. It uses a three-step mathematical trick to generate a sequence of 1s between the start and end positions.

1. Creating the "Ceiling"

((1 << (end + 1)) - 1)

  • This creates a binary number where every bit from position 0 up to end is set to 1.
  • Example: If end = 4, it calculates $(2^5 - 1)$, which is 31 (Binary: 00011111).

2. Clearing the "Floor"

... >> start) << start

  • By shifting the result right and then immediately back left by the start amount, the code effectively "zeros out" any bits below the start position.
  • Example: If our ceiling was 00011111 and start = 2:
    • Shift right by 2: 00000111
    • Shift left by 2: 00011100 (Now only bits 2, 3, and 4 are set).

3. Applying the Mask

reg |= set_val

  • The OR (|) operator ensures that wherever our mask has a 1, the register bit becomes 1. If the register bit was already 1, it stays 1.

Step-by-Step Example

Suppose you have a register with value 0 and you want to set bits from index 2 to 5.

  • Input: reg = 0, start = 2, end = 5
OperationCalculationResult (Binary)
Shift for End1 << (5 + 1)01000000
Subtract 164 - 100111111
Shift Right (Start)>> 200001111
Shift Left (Start)<< 200111100 (The Mask)
Final OR`000111100`

Important Notes for Developers

  • uint16_t for intermediate steps: The code uses a 16-bit integer (uint16_t) for the set_val calculation. This is a smart safety measure. If end is 7, 1 << (7 + 1) results in 256, which would overflow a standard 8-bit variable.
  • Range Limitation: This function assumes end >= start. If start is greater than end, the logic will produce unexpected results (usually 0).
  • Efficiency: This is a "branchless" way to set a range. Instead of using a loop to set bits one by one, it uses pure math to create the mask in a single operation, which is much faster for the CPU.
Upvote
Downvote
Loading...

Input

0 1 3

Expected Output

14