Reputation: 53
Why the following code prints the value of a as -25536 instead of -25535. My guess is that to normalise the short value in the short range it should do 40000-32767 = 7233 and then start from the first range i.e. -32768+7233 = -25535 then where does extra one come from? Why it's -25536?
#include <stdio.h>
int main()
{
short int a = 40000;
printf("%d", a);
return 0;
}
Upvotes: 0
Views: 180
Reputation: 385789
First of all, the correct code is
printf("%hd", a);
Your compiler would have warned you about the problem if you had enabled its warnings. gcc
even gives the solution.
Getting -25,536 is by no means guaranteed. But here's what's happening.
On a little-endian 2's-complement machine with 32-bit int
vars, 40000
is stored as the bytes 40 9C 00 00
.
On a little-endian 2's-complement machine with 16-bit short
vars, the bytes 40 9C
represent -25536.
No operation is performed.
The key two your question is two's complement. You should find this earlier Q&A most relevant.
Upvotes: 0
Reputation: 222714
In the C 2018 standard, 6.3.1.3 3 says conversion to a signed integer type of a value that cannot be represented in the type is implementation-defined. GCC defines the conversion to wrap modulo 2N, where N is the width of the type (the number of bits in the type, including the sign bit).
In the C implementation you are using, short int
has 16 bits, so conversion wraps modulo 216 = 65,536. So 40,000 is converted to short int
by subtracting 65,536 as many times as needed to produce a value into range (−32,768 to +32,767), which is just once: 40,000−65,536 = −25,536.
Note that the bits for 40,000 in pure binary are 1001 1100 0100 0000 (215 + 212 + 211 + 210 + 26 = 32,768 + 4,096, + 2,048 + 1,024 + 64 = 40,000). When interpreted as two’s complement, the leading bit means −32,768 instead of +32,768, so the interpretation of the same bits in two’s complement is −32,768 + 4,096, + 2,048 + 1,024 + 64 = −25,536. This and the arithmetic properties of two’s complement and binary are related to the reason for GCC’s choice to wrap modulo 2N.
Upvotes: 2