为啥 std::cout 输出溢出?

Posted

技术标签:

【中文标题】为啥 std::cout 输出溢出?【英文标题】:Why std::cout output overflow?为什么 std::cout 输出溢出? 【发布时间】:2013-10-10 07:07:11 【问题描述】:

我正在尝试解决 Codeforces (round#1 question A) 上的简单问题。对于第 16 个测试用例,我的代码得到了 -270385980,应该是 27126743055556,但是在我的本地计算机上我可以得到正确的答案。在我的计算机上,我使用 GCC 4.8 编译它,而在 Codeforces 上,我使用了 GCC 4.7。

怎么可能是负数?谁能告诉我我的代码有什么问题?

这是我的代码:

#include <iostream>
#include <cmath>

int main(int argc, char *argv[]) 
    double m, n, a;
    std::cin >> m >> n >> a;
    long long res = static_cast<long>(ceil(m / a)) * static_cast<long>(ceil(n / a));
    std::cout << res;
    return 0;

【问题讨论】:

你提供什么输入? 这是一个 codeforce 的东西,我怀疑他知道。但他的问题几乎可以肯定与整数溢出有关。 @user1166140,您的计算机上的 long longlong 是 64 位值,但在测试计算机上它是 32 位值。再试一次,但这次改用int64_t @OmnipotentEntity - long long 至少需要 64 位宽。 @PeteBecker,实际上不是。参见 N3337 的 4.13.1,也参见 4.5.2 和 4.5.3,它们明确提出了 long long 类型可能无法容纳 char32_twchar_tchar16_t 或可枚举类型的可能性. 【参考方案1】:

以下数字:27126743055556 需要超过 32 位(在 32 位处理器上为 long 的长度)才能表示,因此 long 溢出并且您得到一个负数。

你应该在转换中使用long long

static_cast<long long>(ceil(m / a))

【讨论】:

谢谢亚历克斯,它有效!所以如果乘数是长类型,结果也是长类型,因此在codeforce网站上它溢出(codeforce机器上的长类型可能是32位?)。即使我使用 long long 类型的变量来捕获结果,它也只能得到溢出的结果。

以上是关于为啥 std::cout 输出溢出?的主要内容,如果未能解决你的问题,请参考以下文章

修复表达式中的整数溢出会导致意外行为 [关闭]

与内存有关的那些事儿(数组分配空间不够,导致缓冲区溢出,从而strcpy会出现异常)

当我溢出分配的字符数组时,为啥我的 C 程序不会崩溃?

为啥一个元素在“溢出:可见”时消失,但在“溢出:隐藏”时可见? [复制]

为啥分离线程没有输出消息?

在windows数据栈溢出,在linux系统就没有栈溢出,为啥