Переполнение целых чисел без знака C/С++

Я читаю статью о целочисленной безопасности. здесь ссылка: http://ptgmedia.pearsoncmg.com/images/0321335724/samplechapter/seacord_ch05.pdf

На стр. 166 говорится:

Вычисление с использованием неподписанных операндов никогда не может превышать поток, поскольку результат, который не может быть представлен полученным целым без знака тип уменьшается по модулю до числа, которое больше одного наибольшее значение, которое может быть представлено результирующим типом.

Что это значит? оцените для ответа.

Ответ 1

Это означает, что значение "обертывается".

UINT_MAX + 1 == 0
UINT_MAX + 2 == 1
UINT_MAX + 3 == 2

.. и т.д.

Как говорится в ссылке, это похоже на оператор modulo: http://en.wikipedia.org/wiki/Modulo_operation

Ответ 2

Это означает, что вы не можете изменить знак вычисления unsigned, но он все равно может привести к неожиданным результатам. Скажем, у нас есть 8-битное значение без знака:

 uint8_t a = 42;

и добавим 240 к этому:

 a += 240;

он не подходит, поэтому вы получите 26.

Несвязанная математика четко определена в C и С++, где стандартная математическая форма технически либо undefined, либо зависимая от реализации, либо некоторые другие вещи, которые вы не ожидаете, могут иметь место "(я не знаю точной формулировки, но вывод заключается в том, что" вы не должны полагаться на поведение переполнения в значных целочисленных значениях")

Ответ 3

Нет переполнения?

"Переполнение" здесь означает "создание значения, которое не соответствует операнду". Поскольку применяется арифметический modulo, значение всегда соответствует операнду, поэтому переполнение не происходит.

Другими словами, прежде чем переполнение может действительно произойти, С++ уже усекает значение.

Модульное?

Взятие значения по модулю другого значения означает применить деление и взять остаток.

Например:

0 % 3 = 0  (0 / 3 = 0, remainder 0)
1 % 3 = 1  (1 / 3 = 0, remainder 1) 
2 % 3 = 2  (2 / 3 = 0, remainder 2)
3 % 3 = 0  (3 / 3 = 1, remainder 0)
4 % 3 = 1  (4 / 3 = 1, remainder 1)
5 % 3 = 2  (5 / 3 = 1, remainder 2)
6 % 3 = 0  (6 / 3 = 2, remainder 0)
...

Этот модуль применяется к результатам вычислений без знака, причем делителем является максимальное значение, которое может удерживать тип. Например, если максимум равен 2 ^ 16 = 32768, то 32760 + 9 = (32760 + 9) % (32768+1) = 0.