Ответ 1
Это означает, что значение "обертывается".
UINT_MAX + 1 == 0
UINT_MAX + 2 == 1
UINT_MAX + 3 == 2
.. и т.д.
Как говорится в ссылке, это похоже на оператор modulo: http://en.wikipedia.org/wiki/Modulo_operation
Я читаю статью о целочисленной безопасности. здесь ссылка: http://ptgmedia.pearsoncmg.com/images/0321335724/samplechapter/seacord_ch05.pdf
На стр. 166 говорится:
Вычисление с использованием неподписанных операндов никогда не может превышать поток, поскольку результат, который не может быть представлен полученным целым без знака тип уменьшается по модулю до числа, которое больше одного наибольшее значение, которое может быть представлено результирующим типом.
Что это значит? оцените для ответа.
Это означает, что значение "обертывается".
UINT_MAX + 1 == 0
UINT_MAX + 2 == 1
UINT_MAX + 3 == 2
.. и т.д.
Как говорится в ссылке, это похоже на оператор modulo: http://en.wikipedia.org/wiki/Modulo_operation
Это означает, что вы не можете изменить знак вычисления unsigned
, но он все равно может привести к неожиданным результатам. Скажем, у нас есть 8-битное значение без знака:
uint8_t a = 42;
и добавим 240 к этому:
a += 240;
он не подходит, поэтому вы получите 26.
Несвязанная математика четко определена в C и С++, где стандартная математическая форма технически либо undefined, либо зависимая от реализации, либо некоторые другие вещи, которые вы не ожидаете, могут иметь место "(я не знаю точной формулировки, но вывод заключается в том, что" вы не должны полагаться на поведение переполнения в значных целочисленных значениях")
"Переполнение" здесь означает "создание значения, которое не соответствует операнду". Поскольку применяется арифметический 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
.