这是来自C++ Prime 5th:
如果我们在算术表达式中使用unsigned和int值,则int值通常会转换为unsigned.
我尝试了以下代码:
int i = -40;
unsigned u = 42;
unsigned i2 = i;
std::cout << i2 << std::endl; // 4294967256
std::cout << i + u << std::endl; // 2
Run Code Online (Sandbox Code Playgroud)
因为i + u,如果i被转换为unsigned,它应该是4294967256,然后i + u不能等于2.
如果我们在算术表达式中使用both 和values,那么int值是否总是转换为?unsignedunsignedint
是.
您遇到的是整数溢出.负数的符号由前导符号位给出,其为0(正)或1(负).但是,对于无符号整数,这个前导位只会给你一个整数精度位,而不是符号的指示."否定"有符号数字最终从最大无符号整数大小向后计数.
这与您的特定代码有何关系?好吧,-40确实变成了4294967256.但是,4294967256 + 42不能放入无符号整数,好像你记得-40刚刚变成最大无符号整数减39.这样加上42,就超过了容量你的数据类型.想要的第33位被切断,你从0开始.因此,你仍然得到2作为答案.
Signed: -42, -41, ..., -1, 0, 1, 2
Unsigned: 4294967256, 4294967257, ..., 4294967295, 0, 1, 2, ...
^--^ Overflow!
Run Code Online (Sandbox Code Playgroud)
你可能有兴趣阅读关于Two's Complement的内容