【问题标题】:How to specify 64 bit integers in c如何在c中指定64位整数
【发布时间】:2012-03-25 06:35:28
【问题描述】:

我正在尝试在 C 中使用 64 位整数,但我收到了关于它是否应该可行的混合信号。

当我执行 printf 时:

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

我得到的回应是:

long int 的大小:4 long long int 的大小:8

这让我觉得 long long int 有 8 个字节 = 64 位。

但是,当我尝试声明以下变量时:

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;

最后 4 个变量 (f2,g2,h2,i2) 给我错误信息:

警告:整数常量对于“long”类型来说太大了

当我将 'long long int' 替换为 'int64_t' 时,我得到了相同的结果。我假设 'int64_t' 已被识别,因为它自己没有生成任何错误消息。

所以,看来我的 8 字节长 int 实际上是 6 字节长长 int,我不明白我在这里缺少什么。如果有任何帮助,这里是关于我的 gcc 编译器的信息:

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)   

如果有人知道我如何(或是否)可以访问 64 位整数,我将非常感谢任何帮助。谢谢....

【问题讨论】:

  • 作为LL 后缀的替代,使用-std=c99 编译也应该可以工作。在 C99 中,十六进制整数常量的类型为 long long intunsigned long long int,如果它太大而无法放入 (unsigned) long int,但适合 (unsigned) long long int。不需要后缀。
  • 这里应该提到的一点是,问题不在于 long long int 变量 f2i2,而是您指定的整数文字。在 C89 中,如果给定的值适合该类型,则没有指定后缀的整数文字的类型为 int,否则它的类型为 long int。问题是,0x0000444400004 既不适合int 也不适合long int 类型,这就是编译器所抱怨的。这里的分配不是问题,您将long int 分配给long long int。正如 Daniel 所写,c99 通过允许 long long 文字来解决这个问题。
  • @DanielKamilKozar 我补充说。

标签: c 64-bit sizeof


【解决方案1】:

如何在c中指定64位整数

违反通常的好主意,追加LL

LL 附加到一个整数常量 将确保该类型至少与long long 一样宽。如果整数常量是八进制或十六进制,则常量将在需要时变为unsigned long long

如果不想指定太宽的类型,那么LL 可以。否则,请继续阅读。

long long 可能比 64 位更宽。

今天,long long 不是 64 位的情况很少见,但 C 指定 long long至少是 64 位的。因此,通过使用LL,将来代码可能会指定一个 128 位的数字。

C 有 用于整数常量的宏,在下面的例子中是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);
}

输出

9223372036854775807
0x867530900000000

【讨论】:

    【解决方案2】:

    尝试在数字上添加LL 后缀,编译器可能会将其转换为中间类型作为解析的一部分。见http://gcc.gnu.org/onlinedocs/gcc/Long-Long.html

    long long int i2 = 0x0000444400004444LL;

    此外,编译器丢弃了前导零,因此0x000044440000 变成了0x44440000,这是一个完全可以接受的 32 位整数(这就是为什么在f2 之前没有看到任何警告的原因) .

    【讨论】:

      【解决方案3】:

      对特定大小的整数数据类型使用stdint.h,并对整数文字常量使用适当的后缀,例如:

      #include <stdint.h>
      
      int64_t i2 = 0x0000444400004444LL;
      

      【讨论】:

      • int64_t 既健壮又便携。 long long int 不是。
      • 理论上,int64_t 是可选的。但是,int_least64_tlong long int(从 C99 开始)是标准强制要求的,并且必须至少有 64 位(63 个值位 + 符号位)。
      • 我可以看到 long long int 不健壮,但它怎么不便携?除非你的意思是不可移植=也许/也许不是 64 位。我理解正确吗?现在,我的印象是 int64_t = 64 bits 始终和无处不在。 long long int = 64 位或更多,具体取决于您的 C 实现。
      • 使用 C99 long long int 至少为 64 位,因此这取决于您想要的可移植性 - 如果您可以假设 C99,那么您就可以了。但对我来说,如果你需要一个明确的大小,那么应该明确表达它似乎是“不费吹灰之力” - 它不会花费你任何东西,它更具可读性和不言自明,而且它往往更便携。
      • @doug65536 使用INT64_C(0x0000444400004444) 作为至少 64 位的常量。将添加“适当的”后缀。
      【解决方案4】:

      将 ll 后缀附加到 64 位(long long int)的十六进制数字, 或 ull 后缀为无符号 64 位 (unsigned long long)

      【讨论】:

        【解决方案5】:

        使用 int64_t,可移植的 C99 代码。

        int64_t var = 0x0000444400004444LL;
        

        打印:

        #define __STDC_FORMAT_MACROS
        #include <inttypes.h>
        
        printf("blabla %" PRIi64 " blabla\n", var);
        

        【讨论】:

        • 谢谢,'LL' 后缀似乎是最简单的工作解决方案。所以,我现在需要弄清楚 int64_t 的目的有多少是为了可读性,又有多少是为了真正强制执行 64 位。
        • @user1245262,当你必须有 64 位时使用 int64_t - 即某些数据字段正是这么长。当你需要超过 long 时使用 long long - 那么你明年在 256 位机器上仍然可以!
        • long long int 至少 64位。 int64_t 正好 64 位。
        • 谢谢...这对我来说意义重大。
        • @KarolyHorvath C 至少没有为任何内置类型定义。唯一的要求是 sizeof(char)==1 和 sizeof(long long)>=sizeof(long)>=sizeof(int)>=sizeof(char)。如果您了解您的平台,那么 LL 是一个解决方案。如果您需要跨平台代码,您应该测试 long long 至少为 64 位。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-20
        • 2010-09-14
        • 1970-01-01
        • 2019-03-15
        • 1970-01-01
        • 2013-05-30
        相关资源
        最近更新 更多