Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unsigned long long vs unsigned long(portability point of view)

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?

like image 815
erin c Avatar asked May 17 '12 07:05

erin c


People also ask

What is the difference between unsigned long and unsigned long 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.

What is unsigned long long used for?

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).

What is the difference between long and long long?

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.

Is int64_t same as long long?

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 .


2 Answers

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.

like image 184
James Kanze Avatar answered Nov 15 '22 17:11

James Kanze


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.

like image 31
Alexey Frunze Avatar answered Nov 15 '22 17:11

Alexey Frunze