0

How do you sign extend an 11 bit number to a 32 bit number in C++?

I have the following function, but it is not returning the proper sign-extension as expected:

unsigned int signExtend11to32ui(int i) {
    int mask = 2047; // 0x7FF or 0000 0111 1111 1111
    return static_cast<unsigned int>(static_cast<int>(i & mask));
}

The following function works correctly for sign-extension of 16 bits to 32 bits:

unsigned int signExtend16to32ui(short i) {
    return static_cast<unsigned int>(static_cast<int>(i));
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Erik P.
  • 349
  • 3
  • 13

1 Answers1

2

Since right and left shifts are arithmetic in C++, you can right shift you integer up to most significant bit of int and then back:

std::int32_t i = 2047;
i = (i << 21) >> 21;

this puts -1 to i

myaut
  • 11,174
  • 2
  • 30
  • 62
  • 3
    This might pass the tests, but the result of shifting into the sign bit or right-shifting a negative value is not well-defined. – Bo Persson Mar 11 '17 at 10:17
  • @BoPersson Could you elaborate more on right-shifting not being well defined? – Erik P. Mar 13 '17 at 00:24
  • 3
    @ErikP. - The C++14 standard says: *"The value of `E1 >> E2` is E1 right-shifted E2 bit positions. [...] If E1 has a signed type and a negative value, the resulting value is implementation-defined."* So it might, or might not, work depending on what system you are using. You have to read the compiler manual to see what it is doing. – Bo Persson Mar 13 '17 at 10:47