32位Linux中签名长long数据类型的最大大小是多少

时间:2014-04-17 18:39:16

标签: c++ linux visual-c++ gcc4

我试图在32位Linux平台上运行以下程序。

    int main()
    {
         unsigned long long  val  = 0;
         val   = 140417 * 100000 + 92 + 1;
    }

输出是一些垃圾值(1156798205)。

经过一番研究,我发现:here

 long long size: 64 bits (MAX VALUE: signed long long = 144115188075855871, unsigned long long = 1073741823) 

对于数据类型unsigned long long和signed long long,上面的代码给Visual Studio 2005带来了同样的问题。

但是根据MSDN文档: here

unsigned long long  8 byte  range of values  0 to 18,446,744,073,709,551,615

我想知道如何使用C ++程序在32位Linux平台上处理大范围的值。

谢谢你的帮助。

4 个答案:

答案 0 :(得分:1)

问题是非整数常量的类型(如42)是intlong intlong long int中可以保存其值的最小值,以及表达式的类型由表达式本身决定,而不是由它出现的上下文决定。

因此,如果int恰好是您系统上的32位,那么请执行以下操作:

unsigned long long val = 140417 * 100000 + 92 + 1;

常量140417100000(两者都适合32位)的类型为int,乘法是32位乘法 - 由于乘积而溢出这两个数字不适合32位。 (独立文字的类型根据其值进行调整;较大表达式的类型不是。)

避免这种情况最直接的方法是使用unsigned long long类型的常量:

unsigned long long val = 140417ULL * 100000ULL + 92ULL + 1ULL;

(碰巧并非所有ULL后缀都是必需的,但将它们应用于表达式中的所有常量并没有什么坏处。)

答案 1 :(得分:0)

如果您打印出:sizeof(unsigned long long),则最大值为2 ^(该值)-1。

答案 2 :(得分:0)

问题是虽然您使用的是64位数据类型,但您的计算使用32位值,因此您遇到整数溢出。 140417 * 100000在64位是14041700000(0x344F356A0),但在32位是1156798112(0x44F356A0)。如您所见,0x300000000被截断结果,因为它不适合32位值。

您需要确保使用64位计算,例如:

typedef unsigned long long ulong64_t;

int main()
{
     ulong64_t val = 0;
     val = ulong64_t(140417) * ulong64_t(100000) + 92 + 1;
}

或者,使用整数常量后缀:

int main()
{
     unsigned long long val = 0;
     val = 140417i64 * 100000i64 + 92 + 1;
}

或者:

int main()
{
     unsigned long long val = 0;
     val = 140417ull * 100000ull + 92 + 1;
}

答案 3 :(得分:0)

  

我想知道如何使用C ++程序在32位Linux平台上处理大范围的值。

添加#include <stdint.h>并使用明确long long或最好int64_tuint64_t类型。

最近的海湾合作委员会(例如,现已于2014年4月中旬发布的GCC 4.9)可能有__int128

如果你想处理非常大的数字(绝对值大于2 63 ),所谓的bignums你需要一个bignum库(比如GMPlib) ,或者是一种支持它们的语言(例如Common Lisp,使用SBCL ....)

BTW,以下计划

#include <stdio.h>
int main () {
  unsigned long long val = 0;
  val = 140417 * 100000LL + 92 + 1;
  printf ("val=%lld\n", val);
  return 0;
}

在Linux x86 32位上运行正常。如果省略LL 100000后缀{后缀为LL以获得long long字面值100000常量),则会在integer overflow in expression >使用gcc -Wall hpfe.c -o hpfe ....编译时间。