Sakshi Tanwar
Sakshi Tanwar

Reputation: 53

type conversion query in C

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

Answers (2)

ikegami
ikegami

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

Eric Postpischil
Eric Postpischil

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

Related Questions