【问题标题】:Int64_t overflow problemint64_t 溢出问题
【发布时间】:2011-11-19 17:01:32
【问题描述】:

我在 Windows 7 上使用 Eclipse CDT - Cross G++ Complier (MinGW/msys),这是我的代码:

int64_t y = 1024 * 1024 * 1024 * 4;
std::cout << "type id: " << typeid(y).name() << "; value: " << y << "; size of y: " << sizeof(y) << std::endl;

(IDE 警告:“整数溢出”。)

输出是:

"type id: x; value: 0; size of y: 8"

我不明白,为什么 y 的大小是 8 字节,但值是 0。

感谢您的帮助。

【问题讨论】:

    标签: c++ eclipse g++


    【解决方案1】:

    您应该将文字显式转换为int64_t

    int64_t y = (int64_t)1024 * 1024 * 1024 * 4;
    

    因为1024 * 1024 * 1024 * 4 的字面量是int,而不是int64_t

    【讨论】:

      【解决方案2】:

      您将结果分配给int64_t 的事实无关紧要。重要的是,当您将两个int 类型的值相乘时,结果也具有int 类型。由于 1024、1024、1024 和 4 都是 int 类型的常量,因此生成的临时乘积被计算为溢出的 int

      解决方案是将这些常量中的至少一个设为int64_tint64_tint 的乘积是int64_t,因此 64 位将级联整个乘积。您可以使用显式强制转换或 整数后缀

      int64_t y = (int64_t)1024 * 1024 * 1024 * 4;  // explicit cast
      int64_t y = 1024ll * 1024 * 1024 * 4;  // integer suffix 'll'
      

      整数常量后面的后缀ll(或等效的LL)表示“这个值实际上是long long”。还有ull(或ULL)后缀,用于unsigned long long。另请注意,C 语言标准保证 long long 至少为 64 位。

      【讨论】:

      • 为了便于阅读,请使用1024LL,而不是1024ll。而long long则要求至少为64位;不值得担心它可能不是。
      【解决方案3】:

      当你在 C++ 表达式中写“1024”时,就像你的问题中的那个,你写一个 整数文字,它的大小是 4 个字节,即 32 位(就像它的类型一样intunsigned int),所以最后一次乘以 4 会使 4 字节整数溢出。试试这个:

      int64_t y = ((int64_t)1024) * 1024 * 1024 * 4;
      

      【讨论】:

      • 1024int 类型,可能是也可能不是 32 位,可能是也可能不是 4 字节。
      • 在“Eclipse CDT,Cross G++ Complier”中,没有关于int 大小的“可能是也可能不是”,它总是一些不变的数字,很可能是 4 个字节。但是是的,C++ 标准没有指定 int 的大小,这由编译器决定。
      • 一个小问题:外括号是不必要的:int64_t y = (int64_t)1024 * 1024 * 1024 * 4;
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-21
      • 2011-03-29
      相关资源
      最近更新 更多