I want to be able to use large positive integers(8 bytes) in my project, even though sizeof(unsigned long) yields 8 in my system, I read that in most systems unsigned long is only 4 bytes and I decided to give unsigned long long a go, since it's guaranteed to be at least 8 bytes.
The more I use it though, I saw that it is not super portable as well, for instance in some systems(depending on the compiler) printf formats it with %llu, in some it formats it with %lld.
My code will only run in 64 bit debian machines, in which unsigned long will be 8 bytes. Portability is not a big issue. Is it an overkill to use unsigned long long over unsigned long under these circumstances, are there any other benefits of using unsigned long long over unsigned long?
unsigned long is required to be at least 32 bits. unsigned long long is required to be at least 64 bits. (Actually the requirements are stated in terms of the ranges of values they can represent.) As you've seen, this is consistent with them both being the same size, as long as that size is at least 64 bits.
Unsigned long variables are extended size variables for number storage, and store 32 bits (4 bytes). Unlike standard longs unsigned longs won't store negative numbers, making their range from 0 to 4,294,967,295 (2^32 - 1).
Long long takes the double memory as compared to long. But it can also be different on various systems. Its range depends on the type of application.
The __int8 data type is synonymous with type char , __int16 is synonymous with type short , and __int32 is synonymous with type int . The __int64 type is synonymous with type long long .
unsigned long long
is guaranteed to be at least 64 bits, regardless of the platform. (There are platforms where it is more—I know of 72 bits and 96 bits—but they are rare, and decidedly exotic.) unsigned long
is guaranteed to be at least 32 bits. If you need more than 32 bits, I would recommend unsigned long long
.
With regards to the formatting, with printf
, you should use "%llu"
(since it is unsigned); "%lld"
is for signed long long
.
You can do this if you want to stay with long and long long:
#include <limits.h>
#if ULONG_MAX >= 0xFFFFFFFFFFFFFFFFULL
typedef unsigned long uint64;
#else
typedef unsigned long long uint64;
#endif
W.r.t. this
in some systems(depending on the compiler) printf formats it with %llu, in some it formats it with %lld
printf()
does not guess the format. You tell it the format.
If you want to printf a uint64
defined as in the above, do it like this:
printf("%llu", (unsigned long long)some_uint64_value);
You can typedef unsigned long long ulonglong;
to make the cast easier to type.
There do exist other ways of doing the same, but not all compilers support them. This why I attached the ULL
suffix to the number. In some compatibility modes in-between C89 and C99, 0xFFFFFFFFFFFFFFFF may be interpreted as an unsigned long
, not unsigned long long
, and will be truncated. The latest gcc by default runs in gnu89
mode for C code, not c99
or higher.
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