Reputation:
I am new to C programming and I am currently learning Data types revised chapter. In the below program, my o/p is 36 but compiler is showing the o/p 35.
main( )
{
char ch = 291 ;
printf ( "\n%d %c", ch, ch ) ;
}
Can anyone explain me why the o/p is coming 35? I am currently using GCC 32-bit compiler.
Upvotes: 3
Views: 1632
Reputation: 12002
You're actually making an overflow. A signed character can only go from values -128 to 127 (256 values = 28) in 8-bit character systems (which are pretty much everywhere). So we go with an actual character which value equals 291 % 256 = 35.
Don't forget that the first character is 0, not 1.
Here is actually how a char is represented with the 2's complement system:
unsigned
0 ------- 127 128 ------- 255
signed
0 ------- 127 -128 ------- -1
So actually a signed char c1 = -128
equals an unsigned char c2 = 128
But here this problem is just irrelevant. We're talking about modulo because only the last eight bits are taken into account (where would the other be stored when there are only eight bits available for it in the memory ?).
291 = % 1 0010 0011
(%
means binary representation)
It keeps only the % 0010 0011
which equals 35
and which will be considered exactly the same either you take it signed or not.
Upvotes: 3
Reputation: 224844
Your system apparently has an 8-bit char
type. That means 291
is too big to fit - the compiler reduces it modulo 256 (28) and you end up with 35.
In this case, Clang provides a great warning:
example.c:3:11: warning: implicit conversion from 'int' to 'char' changes value
from 291 to 35 [-Wconstant-conversion]
char ch = 291 ;
~~ ^~~
You should probably avoid relying on this behaviour, since it may vary from implementation to implementation. The C99 and C11 specs (Section 6.3.1.3) say about signed integer conversions:
Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.
Since you're using GCC, you might be interested to read this excerpt from the documentation:
The result of, or the signal raised by, converting an integer to a signed integer type when the value cannot be represented in an object of that type (C90 6.2.1.2, C99 6.3.1.3).
For conversion to a type of width N, the value is reduced modulo 2N to be within range of the type; no signal is raised.
And there you have your full explanation of the reduction modulo 256.
Upvotes: 7
Reputation: 27854
Because a char
can only contain 8 bits of information, and 291 require more than that to be stored. It will then discard the higher bits and keep only what fitted in the variable.
You can simulate that by both bitwise and module operation:
291 % 256 = 35
291 & 0xFF = 35
A 8-bit char can contain values of -128 to 127 or 0 to 255, depending if its signed or unsigned.
Upvotes: 3