tags:

views:

149

answers:

5

What am I doing wrong here?

$ cat size.c
#include<stdio.h>
#include<math.h>

int main() {

printf ("sizeof unsigned int = %d bytes.\n", sizeof(unsigned int));
printf ("sizeof unsigned long long = %d bytes.\n", sizeof(unsigned long long));

printf ("max unsigned int = %d\n", (int)(pow(2, 32) - 1));
printf ("max unsigned long long = %lld\n", (unsigned long long)(pow(2, 64) - 1));

}
$ gcc size.c -o size
$ ./size
sizeof unsigned int = 4 bytes.
sizeof unsigned long long = 8 bytes.
max unsigned int = 2147483647
max unsigned long long = -1
$ 

I am expecting 18446744073709551615 as output instead of a -1 at the last line.


Okay, I completely missed that I was getting the wrong value for 232 - 1, which should have been 4294967295, not 2147483647. Things make more sense now.

+6  A: 

Use %llu, not %lld. d is for signed integers, so printf displays it as a signed long long.

sepp2k
+8  A: 

Just don't suppose that it has a certain value use ULLONG_MAX

Jens Gustedt
`#include <limits.h>` to get this macro, along with others. like `LLONG_MAX` and `LLONG_MIN`.
birryree
@kuropenguin: yes, thanks, I should have mentioned that
Jens Gustedt
+2  A: 

Edit: changed ~0 to (type) -1 as per Christoph's suggestion. See the comments below.

You can get the maximum value of an unsigned type doing the following:

unsigned long long x = (unsigned long long) -1;

Easier, right? =). Second, you are telling printf() to interpret the given variable as a long long decimal, which is signed. Try this instead:

unsigned long long x = (unsigned long long) -1;
printf("%llu", x);

%llu means "long long unsigned".

Santiago Lezica
Actually that should be `~0LLu`
Let_Me_Be
Actually gcc figures that out all by itself.
Santiago Lezica
Though I'd expect it to give some sort of warning.
Nathan Fellman
@Santiago: gcc doesn't figure anythng out here - without the `llu` suffix, it'll only work as intended if `~0 == -1`; casting `-1` actually is the preferred (and portable) method to get the maximum value of any unsigned type, ie `x = (unsigned long long)-1`; the explicit cast is unnecessary if your warning levels are low enough
Christoph
Right you are. Edited! Thanks.
Santiago Lezica
Casting is ugly. Simply write `-1ULL`.
R..
The casting isn't necessary, using `-1` is completely valid. The standard states that the `int` will first be extended to `long long` then cast to `long long unsigned` (which isn't standardized, but always happily converts). This is the same as putting `(long long unsigned) -1` in the first place.
Matt Joiner
@Matt: that's why I said that the explicit cast is unnecessary; it may be needed to make your compiler happy, though (gcc may warn about implicit conversions from signed to unsigned)
Christoph
@R..: what about `size_t` and the types from `stdint.h`, ie if you dont know to which standard integer type your unsigned type corresponds? plain `-1` works fine in all cases, so I prefer that...
Christoph
@Matt: right, but the reason is even simpler than you state. Conversion from signed types to unsigned types is always just computation modulo: `Otherwise, if the new type is unsigned, the value is converted by repeatedly adding orsubtracting one more than the maximum value that can be represented in the new typeuntil the value is in the range of the new type.`
Jens Gustedt
+2  A: 
unsigned long long ulTestMax = -1;
printf ("max unsigned long long = %llu\n", ulTestMax );

this works in C++, should work here, too.

Kiril Kirov
Assuming that the underlying architecture uses two's complement
Nathan Fellman
Also, long long is not a standard type (it's gnu extension, as i remember) and there's no guarantee that it's 64bit
Kiril Kirov
@Nathan: casting `-1` to an unsigned integer type is guaranteed to yield the maximum value by the C standard (specifically, C99 6.3.1.3 §2)
Christoph
Thanks, Christoph!
Kiril Kirov
@Nathan: you're wrong. This has nothing to do with twos complement, only the strictly-defined behavior of unsigned values.
R..
A: 

Whoever done -1 to Kiril Kirov post pls take a look here:

http://stackoverflow.com/questions/809227/is-it-safe-to-use-1-to-set-all-bits-to-true/809341#809341 Dingo post

In Kiril post only slight modification required regarding sign extension:

unsigned long long ulTestMax = -1LLu; 

-1 is antipattern, it'll do the job if u dont want to go with the solution provided by lmits.h

cyber_raj