Виды целочисленного переполнения при вычитании - PullRequest
0 голосов
/ 21 октября 2010

Я пытаюсь снова выучить C ++, используя Sams Teach Yourself C ++ за 21 день (6-е изд.).Я пытаюсь проработать его очень тщательно, убедившись, что понимаю каждую главу (хотя я уже знаком с языками С-синтаксиса).

В начале главы 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

Если я изменю программу так, чтобы строка объявлялась *Вместо 1009 * читается 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, из-за 50, внесенных smallnum.

Третья и четвертая строка Я могу 'объяснитьКак получаются эти результаты?

Редактировать: Для третьей строки - дает ли он этот результат, просто найдя решение по модулю 2^32, которое соответствует диапазону значений, разрешенных для целого числа со знаком?

1 Ответ

1 голос
/ 21 октября 2010

2 ^ 32 - 3000000000 = 1294967296 (!)

...