I\'m working through K&R Second Edition, and can\'t figure out why I\'m getting a certain result. The problem I\'m solving is calculating upper and lower limits for data
Output:
Note:
“In the expression i >>= 1
, a negative value is shifted right. The C standard says this is an implementation-defined operation, and many implementations define it to be arithmetic shift. In an arithmetic shift, the most significant bit is unchanged (keeps MSB (signed bit) = 1
)".
(you can read: Right shifting negative numbers in C that >>
is compiler dependent whether its singed or unsinfed shift, but probably in your case its doing an Arithmetic Shift.)
For this reason after code:
i = ~0;
i >>= 1;
i
remains ~0
. that is in binary == 11111111111111111111111111111111
.
And because ~0
== 11111111111111111111111111111111
is == 2'c complement of 1
that is -1
.
So when you prints with format string %d
it print -1
. You should use %u
to print max unsigned value that is == ~0
.
Important to note here:
§6.2.6.2 Language 45, ©ISO/IEC ISO/IEC 9899:201x
(ones’ complement). Which of these applies is
implementation-defined
, as is whether the value with sign bit1
and all value bits zero (for the first two), or with sign bit and all value bits 1 (for ones’ complement), is a trap representation or a normal value. In the case of sign and magnitude and ones’ complement, if this representation is a normal value it is called a negative zero.
Your understanding that :
~0 >> 1 == 011111111111111111111111111111111
is wrong! (it may be but not happening in your system, according to output)
~0 >> 1 == 111111111111111111111111111111111
, note MSB(signed bit) is 1
.
For unsigned shift, try following:
~0U >> 1 == 011111111111111111111111111111111
Notice Suffix U
for unsigned.
Second printf:
Because i
is -1
, So in second expression -i - 1
== - (-1) - 1
== 1 - 1
== 0
so output is zero : 0
.