For doing a right shift of unsigned values with rounding, the following functions work for me:
unsigned rshift_round_down(unsigned x, unsigned a) {
return x >> a;
}
unsigned rshift_round_up(unsigned x, unsigned a) {
return (x >> a) + ((x & ((1 << a) - 1)) != 0);
}
unsigned rshift_round_halfway(unsigned x, unsigned a) {
return (x >> a) + ((x >> (a - 1)) & 1);
}
unsigned rshift_round_towards_even(unsigned x, unsigned a) {
return (x >> a) + ((x >> (a - ((x & ((1 << a) - 1)) != 1 << (a - 1)))) & 1);
}
Is there a simpler but equivalent implementation of rshift_round_towards_even?
Example inputs and outputs:
- rshift_round_towards_even(60, 2) == 15
- rshift_round_towards_even(61, 2) == 15
- rshift_round_towards_even(62, 2) == 16 (middle towards even is up)
- rshift_round_towards_even(63, 2) == 16
- rshift_round_towards_even(64, 2) == 16
- rshift_round_towards_even(65, 2) == 16
- rshift_round_towards_even(66, 2) == 16 (middle towards even is down)
- rshift_round_towards_even(67, 2) == 17
- rshift_round_towards_even(68, 2) == 17
- rshift_round_towards_even(69, 2) == 17
- rshift_round_towards_even(70, 2) == 18 (middle towards even is up)
- rshift_round_towards_even(71, 2) == 18
- rshift_round_towards_even(72, 2) == 18
- rshift_round_towards_even(73, 2) == 18