I'm a bit confused because I wanted to initialize a variable of type unsigned long
whose size is 8 bytes on my system (on every modern system I suppose). When I want to assign 1 << 63
to the variable, I get a compiler warning however and the number is in fact 0. When I do 1 << 30
I get the expected result of 2 ^ 30 = 1073741824
. Yet when I do 1 << 31
, I get the result of 2 ^ 64
(I think; actually this shouldn't be possible) which prints 18446744071562067968
.
Can anyone explain this behaviour to me?
1 << 63
will be computed inint
arithmetic, and yourint
is probably 32 bit.Remedy this by promoting one of the arguments:
1ULL << 63
will do it.ULL
means the expression will be at least 64 bits.The
1
here, is called an integer constant. By the norms specified in the standard,C11
, chapter§6.4.4.1
the syntax for the same isand regarding the Semantics,
and the table says, if there is no suffix, and the value is representable in the
int
range it should be considered asint
. So,1
here, is considered anint
, which is of generally 4 bytes, or 32 bits, also same in your case.To explicitly specify the
1
asunsigned long
(64) bit, we can use the suffix, likeshould solve your issue.
Please note:
unsigned long
is not guaranteed to be of 64 bits.unsigned long long
is guaranteed to have at least 64 bits. However, as long as you're using the platform whereunsigned long
is of 64 bits , you should be fineI recommend that you use
1ULL
since this will give you a 64-bit unsigned integer on 32 and 64 bit architecture. On 32 Bit architectureunsigned long
(and thereforUL
) is only 32 bit long and will not solve the problem.The expression
1 << 63
has typeint
. The range of anint
is -231 … 231 - 1 on most systems, 263 is too large for that. Try either(unsigned long)1 << 63
or1UL << 63
to shift a value of typeunsigned long
left by 63 places.