We are writing an emulator where we need sign propagating right shift. The emulated system uses 2\'s complement numbers.
I read that the >>
operat
To be portable and avoid implementation defined behavior of right shifting of signed integers, do all shifting with unsigned
.
Follows is a variation on @harold answer. It does not shift by the bit width (which is UB) nor depend on 2's complement. No branching. If on a rare machine not using not 2's complement, could create a trap value.
#if INT_MAX == 0x7FFF && UINT_MAX == 0xFFFF
#define W 16
#elif INT_MAX == 0x7FFFFFFF && UINT_MAX == 0xFFFFFFFF
#define W 32
#else
// Following often works
#define W (sizeof (unsigned)*CHAR_BIT)
#endif
int TwosComplementArithmeticRightShift(int x, int shift) {
unsigned ux = (unsigned) x;
unsigned sign_bit = ux >> (W-1);
y = (ux >> shift) | (((0-sign_bit) << 1) << (W-1-shift));
return y;
}
or as a one-liner
y = (((unsigned) x) >> shift) | (((0-(((unsigned) x) >> (W-1))) << 1) << (W-1-shift));