How to specify 64 bit integers in c
Asked Answered
D

6

62

I'm trying to use 64 bit integers in C, but am getting mixed signals as to whether it should be possible.

When I execute the printf:

printf("Size of long int:%d\nSize of long long int:%d\n\n",(int)sizeof(long int), (int)sizeof(long long int));

The response I get is:

Size of long int:4 Size of long long int:8

This makes me feel that a long long int has 8 bytes = 64 bits.

However, when I try to declare the following variables:

long long int a2 = 0x00004444;
long long int b2 = 0x000044440;
long long int c2 = 0x0000444400;
long long int d2 = 0x00004444000;
long long int e2 = 0x000044440000;
long long int f2 = 0x0000444400004;
long long int g2 = 0x00004444000044;
long long int h2 = 0x000044440000444;
long long int i2 = 0x0000444400004444;

The last 4 variables (f2,g2,h2,i2) give me the error message:

warning: integer constant is too large for ‘long’ type

I get the same result when I replace 'long long int' with 'int64_t'. I assume 'int64_t' was recognized, since it didn't generate any error messages of its own.

So, it appears my 8 byte long long int is really a 6 byte long long int, and I don't understand what I'm missing here. If it's any help, here is the information on my gcc compiler:

me@ubuntu:~$ gcc -v  
Using built-in specs.  
Target: i686-linux-gnu  
Configured with: ../src/configure -v   
--with-pkgversion='Ubuntu/Linaro 4.4.4-14ubuntu5'  
--with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs   
--enable-languages=c,c++,fortran,objc,obj-c++  
--prefix=/usr   
--program-suffix=-4.4   
--enable-shared   
--enable-multiarch   
--enable-linker-build-id   
--with-system-zlib   
--libexecdir=/usr/lib   
--without-included-gettext   
--enable-threads=posix   
--with-gxx-include-dir=/usr/include/c++/4.4   
--libdir=/usr/lib   
--enable-nls   
--with-sysroot=/ -  
-enable-clocale=gnu   
--enable-libstdcxx-debug   
--enable-objc-gc   
--enable-targets=all 
--disable-werror   
--with-arch-32=i686   
--with-tune=generic   
--enable-checking=release   
--build=i686-linux-gnu   
--host=i686-linux-gnu   
--target=i686-linux-gnu  
Thread model: posix  
gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5)   

If anyone knows how (or if) 64 bit integers are accessible to me, I'd really appreciate any help. Thanks....

Diapositive answered 7/3, 2012 at 17:38 Comment(3)
As an alternative to the LL suffix, compiling with -std=c99 ought to work too. In C99, a hexadecimal integer constant has type long long int or unsigned long long int if it is too large to fit in (unsigned) long int, but fits in (unsigned) long long int. No suffix needed.Francinafrancine
One point, that should be mentioned here, is that the problem aren't the long long int variables f2 to i2, but the integer literals you specified. In C89 a integer literal without a specified suffix is of type int if the given value fits into that type, else it has the type long int. The problem is, that 0x0000444400004 doesn't fit neither into the int or the long int type and this is what the compiler is complaining about. The assignment isn't the problem here, you assign a long int to a long long int. As Daniel writes, c99 solves this by allowing long long literals.Ridings
@DanielKamilKozar I added that.Fetishism
S
87

Use stdint.h for specific sizes of integer data types, and also use appropriate suffixes for integer literal constants, e.g.:

#include <stdint.h>

int64_t i2 = 0x0000444400004444LL;
Salubrious answered 7/3, 2012 at 17:42 Comment(9)
Thanks, I suppose I'll have to experiment with this. The 'LL' suffix seemed sufficient. So, I now have to figure out/research if the i64_t is used mainly for readability or to truly force exactly 64 bits tan integer.Diapositive
int64_t is both robust and portable. long long int is not.Salubrious
In theory, int64_t is optional. However, int_least64_t and long long int are (as of C99) mandated by the standard and must have at least 64 bits (63 value bits + sign bit).Francinafrancine
I can see long long int not being robust, but how is it not portable? Unless you mean not portable = maybe/maybe not 64 bits. Am I understanding correctly? Right now, my impression is int64_t = 64 bits always & everywhere. long long int = 64 bits or more depending on your implementation of C.Diapositive
With C99 long long int is at least 64 bits, so it depends on how portable you want to be - if you can assume C99 then you're OK. But to me it seems to be a "no brainer" that if you need an explicit size then that should be expressed explicitly - it doesn't cost you anything, it's more readable and self-explanatory, and it tends to be more portable.Salubrious
How do you use "appropriate" suffixes when one architecture has 64 bit L suffix and another has 32 bit L suffix but a 64 bit LL suffix? This doesn't actually answer the question.Engineman
@doug65536: LL is 64 bits in both the cases that you give.Salubrious
@Engineman Use INT64_C(0x0000444400004444) for a constant at least 64-bit. The "appropriate" suffixes will be added.Tripartite
int64_t i2 = 0x0000444400004444LL; would be fine without the LL. LL serves no purpose here.Tripartite
M
28

Try an LL suffix on the number, the compiler may be casting it to an intermediate type as part of the parse. See http://gcc.gnu.org/onlinedocs/gcc/Long-Long.html

long long int i2 = 0x0000444400004444LL;

Additionally, the the compiler is discarding the leading zeros, so 0x000044440000 is becoming 0x44440000, which is a perfectly acceptable 32-bit integer (which is why you aren't seeing any warnings prior to f2).

Maugham answered 7/3, 2012 at 17:42 Comment(0)
D
6

Use int64_t, that portable C99 code.

int64_t var = 0x0000444400004444LL;

For printing:

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

printf("blabla %" PRIi64 " blabla\n", var);
Dahliadahlstrom answered 7/3, 2012 at 17:44 Comment(5)
Thanks, the 'LL' suffix seems to be the simplest working solution. So, I now need to figure out how much of the purpose of int64_t is for readability and how much is to truly enforce 64 bits.Diapositive
@user1245262, use int64_t when you must have 64bits - ie some data field is exactly this long. Use long long when you need more than long - then you will still be ok on the 256 bit machine next year!Maugham
long long int is at least 64 bits. int64_t is exactly 64 bits.Dahliadahlstrom
Thanks... that's the difference that makes sense to me.Diapositive
@KarolyHorvath C doesn't define at least for any builtin type. The only requirement is sizeof(char)==1 and sizeof(long long)>=sizeof(long)>=sizeof(int)>=sizeof(char). If you know your platform than LL is a solution. If you need cross-platform code you should test that long long is at least 64-bit.Piwowar
T
6

How to specify 64 bit integers in c

Going against the usual good idea to appending LL.

Appending LL to a integer constant will insure the type is at least as wide as long long. If the integer constant is octal or hex, the constant will become unsigned long long if needed.

If ones does not care to specify too wide a type, then LL is OK. else, read on.

long long may be wider than 64-bit.

Today, it is rare that long long is not 64-bit, yet C specifies long long to be at least 64-bit. So by using LL, in the future, code may be specifying, say, a 128-bit number.

C has Macros for integer constants which in the below case will be type int_least64_t

#include <stdint.h>
#include <inttypes.h>

int main(void) {
  int64_t big = INT64_C(9223372036854775807);
  printf("%" PRId64 "\n", big);
  uint64_t jenny = INT64_C(0x08675309) << 32;  // shift was done on at least 64-bit type 
  printf("0x%" PRIX64 "\n", jenny);
}

output

9223372036854775807
0x867530900000000
Tripartite answered 15/6, 2017 at 22:17 Comment(0)
A
1

Append ll suffix to hex digits for 64-bit (long long int), or ull suffix for unsigned 64-bit (unsigned long long)

Alter answered 10/5, 2012 at 13:43 Comment(0)
T
0

Questionable compiler error

Since C99, all 4 constants should compile as is without warning. No LL suffix needed.

long long int f2 = 0x0000444400004;
long long int g2 = 0x00004444000044;
long long int h2 = 0x000044440000444;
long long int i2 = 0x0000444400004444;
// The last 4 variables (f2,g2,h2,i2) give me the error message:
// warning: integer constant is too large for ‘long’ type

With C89, compiler should complain about long long, unless long long available as a compiler extension. In that case, need for a suffix depends on the compiler extension.

Tripartite answered 6/1, 2023 at 15:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.