【问题标题】:Unexpected outputs are coming by only changing the data type仅通过更改数据类型就会出现意外的输出
【发布时间】:2021-07-29 18:19:47
【问题描述】:
unsigned long long int s=0;
s=191689628 +646033877 +109099622 +798412961 +767677318+ 190145527 +199698411;
cout<<s<<endl;

return 0;

上述代码的输出为 18446744072317341664。

unsigned long int s=0;

s=191689628 +646033877 +109099622 +798412961 +767677318+ 190145527 +199698411;
cout<<s<<endl;

return 0;

上面代码的输出是2902757344,这是正确的值。

为什么 unsigned long long int 会给出令人不快的输出?

【问题讨论】:

  • 如果在每个数字上添加ULL 后缀,第一种情况会发生什么?或者在第二种情况下,将UL 添加到每个数字? undefined behavior 导致程序在我的机器上崩溃。
  • gcc 给一个提示:warning: integer overflow in expression [-Woverflow] 并为这两个声明生成 18446744072317341664。
  • 我想@Eljay 关于ull 的东西是对的。 191689628 和所有其他数字都是 有符号整数 4 字节长。编译器将它们加在一起,总和大于 32 位有符号整数的容量,因此发生溢出。 s 在发生溢出后 被分配。将ullul 添加到第一个数字可防止溢出,因为编译器首先分配64 位无符号整数并添加其余部分。
  • @Suthiro "并为两个声明生成 18446744072317341664" - 只有当 long 的大小为 64 位时才会如此。如果它是 32 位大小则不是,这在 OP 案例中显然是正确的。

标签: c++ data-structures long-integer unsigned unsigned-integer


【解决方案1】:

你所有的integer literals 都使用int 类型,所以191689628 + 646033877 + 109099622 + 798412961 + 767677318 + 190145527 + 199698411 的结果超过了int 的最高值,从而溢出。 有符号的整数溢出是未定义的行为

然后,您将溢出的值(negative)分配给 unsigned 类型,这会导致它们各自类型的值很大。 unsigned long long int (通常)比unsigned long int 大,因此差异会更大。这就是您看到这些结果的原因。

为避免溢出,请使用 unsigned 文字开头。

在第一个示例中,将ullULL 后缀添加到每个文字中,以使它们全部为unsigned long long int 而不是int

unsigned long long int s = 0;
s = 191689628ULL + 646033877ULL + 109099622ULL + 798412961ULL + 767677318ULL + 190145527ULL + 199698411ULL;
cout << s << endl;

在第二个示例中,请改用ulUL 后缀:

unsigned long int s = 0;
s = 191689628UL + 646033877UL + 109099622UL + 798412961UL + 767677318UL + 190145527UL + 199698411UL;
cout << s << endl;

Online Demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多