Reputation: 22820
Ok, this is a weird issue :
unsigned long long
variables (I've used even long
ones, with the same effect)sizeof
returns 8, which is fine)However, when I'm trying to go to values like 1<<63
, and perform some simple bitwise operations, I - oddly - seem to be getting negative values. Why's that?
My test code :
unsigned long long c = 0;
c |= 1l << 56; printf("c = %lld\n",c);
c |= 1l << 63; printf("c = %lld\n",c);
Output :
c = 72057594037927936
c = -9151314442816847872
Sidenotes :
c = 1l<<63
directly.Any suggestions?
Upvotes: 9
Views: 7614
Reputation: 57168
I think you're actually doing something undefined here. I think the expression 1l << 63
is undefined in C, since the compiler will represent 1l
in a signed type, and shifting by 63 bits causes an signed overflow (which is undefined in C). I'm not an expert, but seems like you want 1ull << 63
.
Your original code, in fact, complains about this if you pass -Weverything
in clang:
foo.c:7:23: warning: signed shift result (0x8000000000000000) sets the sign bit of the
shift expression's type ('long') and becomes negative [-Wshift-sign-overflow]
c |= 1l << 63; printf("c = %lld\n",c);
~~ ^ ~~
EDIT: And, yes, then you need the correct printf format from the other answer.
Upvotes: 4
Reputation: 18492
The d
part of the %lld
specifier is telling printf
that the argument should be treated as a signed integer. Use a u
instead: %llu
.
From the man pages:
d, i
The int argument is converted to signed decimal notation.
o, u, x, X
The unsigned int argument is converted to unsigned octal (o), unsigned decimal (u), or unsigned hexadecimal (x and X) notation.
Upvotes: 22