我正在阅读有关整数安全性的文章。这是链接: http: //ptgmedia.pearsoncmg.com/images/0321335724/samplechapter/seacord_ch05.pdf
第166页说:
涉及无符号操作数的计算永远不会溢出,因为无法由生成的无符号整数类型表示的结果会以比结果类型可以表示的最大值大一的数字为模减少。
这是什么意思?感谢回复。
我正在阅读有关整数安全性的文章。这是链接: http: //ptgmedia.pearsoncmg.com/images/0321335724/samplechapter/seacord_ch05.pdf
第166页说:
涉及无符号操作数的计算永远不会溢出,因为无法由生成的无符号整数类型表示的结果会以比结果类型可以表示的最大值大一的数字为模减少。
这是什么意思?感谢回复。
这意味着价值“环绕”。
UINT_MAX + 1 == 0
UINT_MAX + 2 == 1
UINT_MAX + 3 == 2
.. 等等
正如链接所说,这就像模运算符:http ://en.wikipedia.org/wiki/Modulo_operation
这里的“溢出”意味着“产生一个不适合操作数的值”。因为应用了算术模,所以值总是适合操作数,因此不会溢出。
换句话说,在溢出实际发生之前,C++ 已经截断了该值。
取一个值取模某个其他值意味着应用除法,然后取余数。
例如:
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
.
这意味着您无法更改unsigned
计算的符号,但仍会产生意想不到的结果。假设我们有一个 8 位无符号值:
uint8_t a = 42;
我们再加上 240:
a += 240;
它不适合,所以你得到 26。
无符号数学在 C 和 C++ 中明确定义,其中有符号数学在技术上要么是未定义的,要么是依赖于实现的,或者是其他一些“你不会期望可能发生的事情”的措辞(我不知道确切的措辞,但结论是“你不应该依赖有符号整数值的溢出行为”)