减法时整数溢出的种类

发布于 2024-09-28 12:48:08 字数 1484 浏览 5 评论 0原文

我正在尝试使用 Sams 的《21 天自学 C++》(第 6 版)重新学习 C++。我正在尝试非常彻底地完成它,确保我理解每一章(尽管我已经熟悉 C 语法语言)。

在第 5 章(清单 5.2)开头附近,提出了有关无符号整数溢出的问题。根据他们的示例,我写了这样的:

#include <iostream>

int main () {
    unsigned int bignum = 100;
    unsigned int smallnum = 50;
    unsigned int udiff;
    int diff;
    udiff = bignum - smallnum;
    std::cout << "Difference (1) is " << udiff << "\n";
    udiff = smallnum - bignum;
    std::cout << "Difference (2) is " << udiff << "\n";
    diff = bignum - smallnum;
    std::cout << "Difference (3) is " << diff << "\n";
    diff = smallnum - bignum;
    std::cout << "Difference (4) is " << diff << "\n";
    return 0;
}

这给出了以下输出,这对我来说并不奇怪:

Difference (1) is 50
Difference (2) is 4294967246
Difference (3) is 50
Difference (4) is -50

如果我更改程序,以便声明 bignum 的行改为读取 unsigned int bignum = 3000000000; 那么输出是

Difference (1) is 2999999950
Difference (2) is 1294967346
Difference (3) is -1294967346
Difference (4) is 1294967346

第一个显然没问题。 数字 1294967346 的解释是 1294967346 恰好是 2^32 - 3000000000。我不明白为什么第二行没有读取 1294967396,因为 smallnum 贡献了 50。

第三行 和第四行 < /strike> 我无法解释。这些结果是如何产生的?

编辑:对于第三行 - 它是否仅通过找到适合有符号 int 允许的值范围的模 2^32 的解决方案来给出此结果?

I'm making an attempt to learn C++ over again, using Sams Teach Yourself C++ in 21 Days (6th ed.). I'm trying to work through it very thoroughly, making sure I understand each chapter (although I'm acquainted with C-syntax languages already).

Near the start of chapter 5 (Listing 5.2), a point is made about unsigned integer overflow. Based on their example I wrote this:

#include <iostream>

int main () {
    unsigned int bignum = 100;
    unsigned int smallnum = 50;
    unsigned int udiff;
    int diff;
    udiff = bignum - smallnum;
    std::cout << "Difference (1) is " << udiff << "\n";
    udiff = smallnum - bignum;
    std::cout << "Difference (2) is " << udiff << "\n";
    diff = bignum - smallnum;
    std::cout << "Difference (3) is " << diff << "\n";
    diff = smallnum - bignum;
    std::cout << "Difference (4) is " << diff << "\n";
    return 0;
}

This gives the following output, which is not surprising to me:

Difference (1) is 50
Difference (2) is 4294967246
Difference (3) is 50
Difference (4) is -50

If I change the program so that the line declaring bignum reads instead unsigned int bignum = 3000000000; then the output is instead

Difference (1) is 2999999950
Difference (2) is 1294967346
Difference (3) is -1294967346
Difference (4) is 1294967346

The first of these is obviously fine. The number 1294967346 is explained by the fact that 1294967346 is precisely 2^32 - 3000000000. I don't understand why the second line doesn't read 1294967396, owing to the 50 contributed by smallnum.

The third and fourth lines I can't explain. How do these results come about?

Edit: For the third line - does it give this result just by finding the solution modulo 2^32 that fits in the range of values allowed for a signed int?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

顾铮苏瑾 2024-10-05 12:48:08

2^32 - 3000000000 = 1294967296(!)

2^32 - 3000000000 = 1294967296 (!)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文