2

I am playing with type conversions when I came across this in the following code.

int i = 123456;
short s = i;
printf("%i",s);

Here an int value is converted to short implicitly by C compiler. Printing this value, results in -7616 on the console output. I understand that short has a smaller range than that of int but I need to know how C language came to this value -7616 from 123456 instead of truncating it, which I guess is the intuitive option.

4 Answers4

8

The value is being truncated, but not in the way you expect.

The decimal value 123456 has hex value 0x1E240. When assigning this value to a short, which in your case appears to be 16 bits, it takes just the lower 16 bits, which is 0xE240.

If s were an unsigned short, it would have the value 57920. But because it's signed, the value is interpreted as such. Since your machine appears to be using two's complement representation for negative numbers, the decimal equivalent of 0xE240 is -7616 (= 57920 - 65536).

Note that this behavior is implementation defined, so you can't depend on this happening on different machines or different compilers.

cxw
  • 16,685
  • 2
  • 45
  • 81
dbush
  • 205,898
  • 23
  • 218
  • 273
1

Values get truncated during this conversion in such a way that the less significant bits are preserved, but the higher bits are lost. This is consistent whether you use a big or little endian machine.

In your specific example, 123456 is written as 11110001001000000 in binary. Keep in mind that ints use 4 bytes, so there are a bunch of leading zeros that I omitted from that number. Shorts are limited to 2 bytes, immediately truncating the number to 1110001001000000 strictly. Notice that there is a 1 in front, which in 2's complement would immediately indicate a negative number. Going through the 2's complement process shows how you would get the result you did.

In C, when you convert an int to a short, you are already asking for trouble. In cases like when working with .wav files, you typically use int datatypes for manipulation of attributes before using a series of if statements to control truncation.

//you will need to #include <limits.h>

int i = 123456;
short s;

if(i > SHRT_MIN && i < SHRT_MAX) //if your int is within the range of shorts
{
    s = i;
}


//if your int is too large or too negative, you can control the truncation

if(i < SHRT_MIN) //if int is too negative
{
    i=SHRT_MIN;
}

else //if int is too positive
{
    i=SHRT_MAX;
}
MacedonZero
  • 216
  • 1
  • 9
0

Let's imagine a 4bit integer is converted to a 2bit integer. The first bit determines whether the number is positive (0) or negative (1). 0111 (dec: 7) converts to 11 (dec: -1). It will cut higher bits. And since the first bit 1 represents - it will be negative.

Shiro
  • 2,610
  • 2
  • 20
  • 36
0

Data type short (2 byte size) has values from [-32768] to [32767].

int main()
{
    int i = 32767;
    short c = i;
    printf("%d\n",c);
    c = i+1;
    printf("%d\n",c);
    c = i+2;
    printf("%d\n",c);
}

//Output:
32767
-32768  << rolling
-32767  << rolling

If you see the values keep on rolling from least value (-32768) to max values if short is assigned values greater than allowed max value i.e [32767]

int main()
{
    int i = -32768;
    short c = i;
    printf("%d\n",c);
    c = i-1;
    printf("%d\n",c);
    c = i-2;
    printf("%d\n",c);
}

//Output:
-32768
32767  << rolling
32766  << rolling

If you see the values keep on rolling from max value (32767) to least values if short is assigned values less than allowed min value i.e [-32768]

sameerkn
  • 2,209
  • 1
  • 12
  • 13