Bit offset with unsigned long type leads to incorrect results
I'm a little confused because I wanted to initialize a type variable unsigned long
that is 8 bytes in size on my system (on every modern system, I suppose). When I want to assign to a variable 1 << 63
, I get a compiler warning and the number is actually 0. When I do 1 << 30
, I get the expected result 2 ^ 30 = 1073741824
. But when I do 1 << 31
, I get a result 2 ^ 64
(I guess it shouldn't actually be possible) that prints 18446744071562067968
.
Can anyone explain this behavior to me?
source to share
This 1
is referred to as an integer constant. According to the norms specified in the standard C11
, chapter ยง6.4.4.1
, the syntax for it is
integer constant: decimal-constant integer-suffix opt
octal integer-suffix constant opt hexadecimal constant integer-suffix <sub> manualsub>
and regarding semantics,
The type of an integer constant is the first in the corresponding list in which its value can be represented.
and the table states that if there is no suffix and the value is presented in a range int
, it should be treated as int
. So 1
what is considered here as int
which usually has 4 bytes or 32 bits is also the same in your case.
To explicitly specify a bit 1
as unsigned long
(64), we can use a suffix like
1UL << 63
should solve your problem.
Please note: unsigned long
it cannot be 64 bits. unsigned long long
guaranteed to have at least 64 bits . However, as long as you are using a platform where it unsigned long
has 64 bits, you should be fine
source to share