I am trying to make a test to tell whether my PC performs arithmetic or logical right shift by right-shifting hexadecimal FFFFFFFF
by 1
.
I know that an integer -1
reads as FFFFFFFF
in hexadecimal since it is the two's complement of 1
. Right-shifting -1
by 1
results in FFFFFFFF
and shows the PC performed arithmetic right shift.
But if I just type in 0xFFFFFFFF >> 1
, it resulted in 7FFFFFFF
and shows that the PC performed logical right shift instead. Why did that happen? See for the code below that produced the results:
#include <stdlib.h>
#include <stdio.h>
int main ( int argc, char *argv[] )
{
printf ( "%x >> 1 = %x\n", -1, -1 >> 1 );
printf ( "%x >> 1 = %x\n", 0xffffffff, 0xffffffff >> 1 );
return EXIT_SUCCESS;
}
The program's output was:
ffffffff >> 1 = ffffffff
ffffffff >> 1 = 7fffffff
It is not an assumption. What type do you think 0xffffffff
is ? According to the C standard, 6.4.4.1 Integer constants, the type of the expression of a hexadecimal constant (preceded with 0x
) is the first of the following which can applicably hold the represented value:
int
unsigned int
long int
unsigned long int
long long int
unsigned long long int
On your platform, 0xFFFFFFFF cannot be represented as int
because int
is 32 bits and only 31 bits express quantity in signed int
(the standard dictates one bit is reserved for sign). The next type, unsigned int
, is therefore used. Therefore no sign bit is present to extended with the shift operation, which is thereby logical rather than arithmetic.
It may not be apparent how I concluded int
was 32 bits on your platform. Indeed I could not make that assumption were it not for the first line, which arithmetic-right-shifts the value of -1
. The result of that shift, dumped as %x
, was 0xFFFFFFFF
. Had int
been native 64-bits that should dump 0xFFFFFFFFFFFFFFFF
instead. Without that prior knowledge, no single type conclusion of 0xFFFFFFFF
could be assumed since it may well be representable as a standard signed int
of width 64-bits (63+1) with value 0x00000000FFFFFFFF
. The resulting shift would produce the same output you see now, thereby introducing an alternative to that postulated above.
Your main question is: is 0xffffffff
unsigned?
From C11 §6.4.4.1 Integer constants
The type of an integer constant is the first of the corresponding list in which its value can be represented.
The output of your first printf
line suggests that int
is 32-bit on your machine. Thus it can not represent 0xffffffff
, it must be unsigned.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With