#include <stdio.h>
#include <stdint.h>
// Define macros here
#define SET_ENABLE(x,val) \
( (val ? (x |= (0x1U << 0)) : (x &= (~(0x1U << 0)))) )
#define SET_MODE(x, val) \
do {\
x &= (~(0x3U << 1)); \
x |= ((val & 0x3U) << 1); \
} while (0)
#define SET_SPEED(x, val) \
do { \
x &= (~(0x7U << 3)); \
x |= ((val & 0x7U) << 3); \
} while (0)
#define SET_RESERVED(x) (x &= (~(0x3U << 6)))
uint16_t build_register(uint8_t enable, uint8_t mode, uint8_t speed) {
// Use macros to set fields
uint16_t reg = 0;
SET_ENABLE(reg, enable);
SET_MODE(reg, mode);
SET_SPEED(reg, speed);
SET_RESERVED (reg);
return reg;
}
int main() {
uint8_t enable, mode, speed;
scanf("%hhu %hhu %hhu", &enable, &mode, &speed);
uint16_t reg = build_register(enable, mode, speed);
printf("%u", reg);
return 0;
}To set one bit, since its either 0 or 1, we check the value of the user input, then set or clear the first bit of the register. If you dont want to use the ternary operator i.e (condition ? expression_if_true : expression_if_false;) you can use the do while syntax like:
c
#define SET_ENABLE(x, val) \
do { \
if (val){ x |= (0x1U << 0); } \
else { x &= (~(0x1U << 0)); } \
} while (0)To set the mode of register(x), which requires two bits. We use the value 3 dec as a mask since 3 dec in binary is 11, First step is to clear the two bits in position 1 & 2, this is done by left shifting the inverted mask (3) two times.
x &= ( (~(0x3U)) << 1 )The next step is to now set the bits in position 1 & 2 using the val given by the user, we modify the mask by anding with the user input, then left shift it to bits 1 & 2.
x |= ( (val & 0x3U) << 1 )To set the speed, we need to modify three bits, so our mask is 7 dec which is 111 in binary. The first step as usual is to clear the three bits of the register (x) from bit position 3 to 5:
x &= ( (~(0x7U)) << 3 )The next step is to set the bit 3 to 5 of the register (x), first we AND it with the mask to change the mask to the user bits, then left shift to affect bits 3-5 only.
x |= ( ((0x7U) & val) << 3)For the Reserved bits, they are two of them, So the mask becomes 3 dec == 11 binary.
x &= ( (~(0x3U)) << 6 )Input
1 2 4
Expected Output
37