Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how signed and unsigned integers are stored in c?

Tags:

c

I am trying to run the following code but confused with what's happening here:

int main()
{
 /* 
    a = -1; 
    b = 0xffffffff; 
 */
if(-1 == 0xffffffff )
        printf("-1 is equal to maximum\n");
else
        printf(" -1 is not equal to maximum\n");

if(0xff < -1)
        printf(" Less than -1 \n");
if(0xff < 0xffffffff)
        printf(" Less than maximum\n");

I tried with commented section as well and replaced -1 with "a" and 0xffffffff with "b" but the result is same .

It's 32 bit system so i have taken integer size 4 bytes.

My Output is :

-1 is equal to maximum
 Less than maximum

If -1 is equal to maximum then it should execute both of the last two if statements. But it's not happening. Why?

like image 376
Omkant Avatar asked Sep 10 '12 11:09

Omkant


2 Answers

I'll quote this from C++; I think it's the same for C:

The literal -1 is always a signed int.

The literal 0xff is a signed int, but 0xffffffff is an unsigned int.

In comparisons of mixed signs, both operands are converted to unsigned, explaining all your results.

Here's the rule about the types of naked integral literals (i.e. without type suffix) from C++11, table 6:

  • Decimal literals are of the smallest type among int, long int or long long int, whichever fits.

  • Hexadecimal literals are of the smallest type among int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, whichever fits.

To spell it out again:

  • In your first comparison, both sides are converted to unsigned int, giving the value 0xFFFFFFFF.

  • In the second comparison, both terms are signed integers, and the left term is 255 and the right term is -1.

  • In the third comparison, both terms are converted to unsigned int.


Observe that we never needed to worry about hardware implementations of signedness for this question. The only relevant platform-dependent value is the size of int, which we used when we asserted that 0xffffffff does not fit into an int but does fit into an unsigned int.

like image 96
Kerrek SB Avatar answered Sep 22 '22 18:09

Kerrek SB


In C/C++, negative numbers are stored in 2's compliment format and Most Significant Bit(MSB) acts as a sigh indication.

MSB 1 means -ve and MSB 0 means +ve. 1xxxxxxxxxx is -ve number and 0xxxxxxxxxx means +ve. In 1xxxxxxx the "xxxxxx" is 2's compliment of a number. And in 0xxxxxx the "xxxxx" is actual binary representation of a number.

Compiler interpret number as -ve if MSB(sign bit) is 1 and understands the number has to be the two's compliment.

First lets see what is 2's compliment:

2's compliment is negating an actual number(all bits) and then adding 1.

decimal 1 = 00000001

~ decimal 1 = 11111110

2's compliment of decimal 1 = 11111111 (F hex)

so -1 becomes = (1) 111111111111111

(1) is a MSB indicating -ve number the rest is the 2's compliment of a number.

thus -1 = 0xFFFFFFFF

You can try out printing binary representation of some -ve numbers and comparing the 2's compliment of binary representation of a number.

like image 36
Sandesh Kobal Avatar answered Sep 21 '22 18:09

Sandesh Kobal