-1

I need to find the most significant bit of signed int N and save it in signBitN. I want to do this using bitwise only operations. Also, how would I make signBitN extend so that all its bits are equal to its significant bit. i.e. if it's significant bit was zero, how would I extend that to be 00000...00? The closest I've gotten is signBitN=1&(N>>(sizeof(int)-1));

2 Answers2

3

Portable expression:

1 & (x >> (CHAR_BIT * sizeof(int) - 1))

Latest C standards put 3 standards on representation of ints.

  • sign and magnitude
  • one complement
  • two complement See section 6.2.6.2 Integer types of C11 standard.

Only the third option is relevant in practice for modern machines. As specified in 6.2.6.1:

Values stored in non-bit-field objects of any other object type consist of n x CHAR_BIT bits, where n is the size of an object of that type, in bytes.

Therefore int will consist of sizeof(int) * CHAR_BIT bits, likely 32. Thus the highest bit of int can be read by shifting right by sizeof(int) * CHAR_BIT - 1 bits and reading the last bit with bitwise & operator.

Note that the exact value of the int after the shift is implementation defined as stated in 6.5.7.5.

On sane machines it would be:

int y = x < 0 ? -1 : 0;

The portable way would be casting between int and an array of unsigned char and setting all bytes to -1. See 6.3.1.3.2:

if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.

And 6.2.6.1.2

Values stored in unsigned bit-fields and objects of type unsigned char shall be represented using a pure binary notation.

You can use memset() for that.

int x;
memset(&x, (x < 0 ? -1 : 0), sizeof x);
tstanisl
  • 13,520
  • 2
  • 25
  • 40
  • 1
    If `x` is negative then `x >>` has an implementation-defined result. Some implementations may fill with zero bits , for example. – M.M Feb 28 '21 at 22:27
  • @M.M, yes it's implementation defined. But the question was about value of the highest bit *before* shifting – tstanisl Feb 28 '21 at 22:32
  • The entirety of the result is implementation-defined ; the standard doesn't guarantee that your first suggestion will give the right answer . So perhaps "portable" is not a good description of that code. – M.M Feb 28 '21 at 22:57
  • @M.M Yes. The result of the operation is implementation defined because the bit representation of 'int' is implementation defined. Maybe first the concept of the highest bit should be defined. – tstanisl Feb 28 '21 at 23:02
  • @tstanisl so why to use it if t is not portable? – 0___________ Feb 28 '21 at 23:17
0

If the question is how to check the MSB bit of the integer (for example 31st bit of the 32 bit integer) ten IMO this is portable.

#define MSB(i)   ((i) & (((~0U) >> 1) ^ (~0U)))
#define issetMSB(i) (!!MSB(i))

int main(void)
{
    printf("%x\n", MSB(-1));
    printf("%x\n", issetMSB(-1));
}
0___________
  • 60,014
  • 4
  • 34
  • 74