正整数的 原码 补码 反码 都是一样的
负数的反码是将其原码除 符号位之外的各位取反
负数的补码是将其原码除 符号位之外的各位取反 再在末尾加1
假设 存在 一个字节的整型 signed int8 x = -5
x的原码1000 0101(最高位是符号位 1表示负 0表示正)
x的反码1111 1010
x的补码1111 1011
储存的计算中的 -5 不是我们更能理解的10000101,而是 -5 的补码1111 1011
现在 回答你的问题:
unsigned int e,f=12345;
f是无符号 所以 f的 原码 补码是一样的:0000 0100 1101 0011
因此c还是等于12345
signed int c,d=-15;
d是负数 所以 d的原码是1000 0000 0000 1111
d的补码是1111 1111 1111 0001
c = f = 0000 0100 1101 0011 转换成 十进制 就是 12345
e = d = 1111 1111 1111 0001 因为e是无符号整型 所以计算机直接将
1111 1111 1111 0001 当做正整数来处理的,没有了补码转换成原码的过程了。
因此你看到的e不是等于 -15 (用十进制表示)而是 65521(用十进制表示)
总结:这个问题的关键是 我们在计算机屏幕上看到的是 原码;而储存的计算中的是 补码。正整数的原码 补码是一样的,而负数的原码 补码是 不一样的,
如果你了解这个概念的话,这个问题就很容易理解了
(signed)var 直接强制转换
可以=赋值运算符, 但是要加上强制转换在c中如int 要转为long 那么这样转:
int num1 = 5;
long num2 = (int)num1;
在c++你也可以用c的方式转换也可以用c++的方式:
int num1 = 5;
long num2 = static_cast<int>(num1);
精度的转换 ,会不可避免的造成精度的丢失。