I have written the following function which is meant to extract bits 5 through 8 (inclusive) of an integer and return those bits. However, the extracted bits are treated as signed so therefore they must be sign extended after bit shifting.
int signedBits5through8(int v){
int fourBits = (v & 0b111111111) >> 5;
int signBit = (fourBits & 0b1000) >> 3;
return (0b11111111111111111111111111110000 * signBit) | fourBits;
}
In order to achieve sign extension, my implementation multiplies the sign bit (the most significant bit of the extracted 4 bits, following twos complement conventions) by 28 bits of 1s followed by 4 bits of zeros in order to "sign extend", and then uses an OR mask to apply the last 4 bits. My issue is that I am unable to use any operators other than bitwise ones for this task, and so using the multiplication operator is unacceptable. What's the best work-around in this situation? I also cannot use any conditional or loop logic (if-else, for, etc) in my function.
As @user207421 suggested in the comments, you can sign-extend by bit-shifting without using the sign bit explicitly.
Note that before c++20 when two's complement representation was not yet required by the standard, this was considered conditionally UB (even though MSVC seems not to think so, which is probably a compiler bug) if the left shift causes signed overflow.
As code, the suggestion looks like this:
Here are some tests to show it works as intended in all the major compilers, using constant evaluation to ensure that no UB is evaluated (at least with c++20 standard enabled): https://godbolt.org/z/6aonbxsbs