Reputation: 627
I have a simple program with a short variable declaration:
short int v=0XFFFD;
printf("v = %d\n",v);
printf("v = %o\n",v);
printf("v = %X\n",v);
The result is:
v = -3 ; v = 37777777775 ; v = FFFFFFFD
I don't understand how to calculate these values. I know that a short variable can hold values between -32768 and 32767, and the value 0XFFFD causes an overflow, but I don't know how to calculate the exact value, which is -3 in this case.
Also, if my declaration is v=0XFFFD why the output v=%X is FFFFFFFD?
Upvotes: 0
Views: 2126
Reputation: 29724
If short is 2 bytes on this machine then 0x8000 is binary representation of the biggest negative value this type holds that is -32768. Because of how things are designed, next numbers are represented by corresponding next bit patterns, i.e:
biggest negative value = 0x8000 = -32768
0x8001 = biggest negative value + 1 = -32767
0xFFFF = biggest negative value + 0x7FFF = -1
0xFFFE = biggest negative value + 0x7FFE = 0xFFFF - 1 = -2
0xFFFD = biggest negative value + 0x7FFD = 0xFFFF - 2 = 0xFFFE - 1 = -3
Upvotes: 2
Reputation: 14359
First of all a short
can be as short as 16 bits (which probably is the case on your compiler). This means that 65533
can't be represented correctly, the assignment overflows, it wraps to -3
(as short int
is a signed short integer). But you already knew that.
Secondly when sent as an argument to printf
the short int
is converted to int
automatically, but as v
contains -3
that's the value that is sent to printf
.
Thirldly the %o
and %X
conversions expect an unsigned int
which is not quite what you've supplied. This means undefined behavior (in theory), but in practice it's quite predictable. This means that the bit pattern for -3
is interpreted as an unsigned integer istead which on 32 bit machines happens to be 0xFFFFFFFD
.
Upvotes: 5
Reputation: 44284
but I don't know how to calculate the exact value,which is -3 in this case.
The most common way of representing integer numbers in computers are 2's complement.
If you have an n-bit integer, you get the decimal value like this:
Decimal value = - bn-12n-1 + bn-22n-2 + ... + b121 + b020 where bi is the value of bit number i.
In your case you have a 16 bit variable. The hexadecimal representation is 0xfffd which in binary is 1111.1111.1111.1101
Inserting into the formula you'll get:
Decimal value = - 1*215 + 1*214 + ... + 1*22 + 0*21 + 1*20 = - 3
See https://en.wikipedia.org/wiki/Two%27s_complement for more about the subject.
Upvotes: 1
Reputation: 11
The number 0xFFFD does not cause an overflow, since -3 is perfectly within the range of -32768 through 32767.
Any short variable is a signed two's complement and the result of -3(decimal) is calculated like any two's complement value. So to find out how to calculate the result of -3(decimal) please take a look on the many tutorials on youtube or in any pertinent textbooks.
Your compiler seems to conduct an implicite type conversion of your short variable to an int value before it prints the number as an int. To do that it has to carry out a so called sign extension since it has to make a 32-bit signed two's complement out of a 16-bit signed two's complement. Just like with any decimal number there are an infinite amount of zeros preceding the number (for example 34 = 0034) there are an infinite number of 1s preceding a negative two's complement number. So the compiler copies the most significand bit to the left. makin 0xFFFFFFFD out of 0xFFFD and 37777777775(oct) out of 177775(oct) i.e. (00)1 111 111 111 111 101 (bin).
I hope that information helped you.
Upvotes: 1