Suppose we have an index that fits in a u27, and a flag that fits in a u5. We can store both in a u32 as either:

(index << 5) + flag
(flag << 27) + index

In practice, is there any advantage/standard for picking one over the other? [Context: compressing stuff in b tree nodes, so not using 2 u32 is important]

You could do it without bit shifting, using u32 flags that are multiples of 2^{27}, combine them with | (bitwise or), and extract the values with & (bitwise and) and an appropriate mask. In that case, the representation would be the

(flag << 27) + index

version. Disclaimer: I donâ€™t know about practical advantages/standards and donâ€™t have any experience doing something like this myself.

Iâ€™d assume your k is actually a constant? Then it doesnâ€™t really matter how you calculate it, and I would maybe just put the mask in a const.

const LOWER_27_BITS: u32 = (1 << 27) - 1;

Iâ€™m personally not aware of any more idiomatic approach. You have to make sure to use 28 in the shift for getting 27 bits to be 1 use parentheses even though the shift is used somewhat like an exponential here, and exponentiation usually binds tighter than addition. Maybe itâ€™s slightly less confusing to use 2.pow thenâ€¦

Thanks, good catch. Makes sense now, thinking about it again. I've messed up my testing by forgetting the parentheses, so that the result of 1 << 28 - 1 looked closer to the correct anwer. But only because that's 1 << (28 - 1).

So the code I had wouldn't have given 27 ones or 28 ones but instead a single one followed by 27 zeroes.