补码复习
正数和负数的补码区别
1) 对于正数,原码和补码相同
2) 对于负数,先得到反码,再计算补码
反码:除符号位外取反
补码:反码+1
补码示例
1) 35
原码:0010,0011
补码:0010,0011
2) 18
原码:0001,0010
补码:0001,0010
3) -18
原码:1001,0010
反码:1110,1101
补码:1110,1110
计算机中的加减就是补码的加减
1) 35+18
因为补码是可以连同符号位一起运算,所以运算法则等同于无符号二进制运算:
0010,0011 --35二进制表示
0001,0010 --18二进制表示
0011,0101 --转换成10进制是53。结果正确!
2) 35+(-18)
运算规则等同于无符号二进制加法:
0010,0011 --35的补码
1110,1110 -- -18的补码
1,0001,0001
因为前面规定了字长是8位,这里出现了9位,所以最高位舍弃,
舍弃后,结果为00010001,转换成十进制是:17。结果正确!(超出字长部分直接舍弃)
用16进制初始化负的int变量时, 注意要写补码
1) 因为计算机中都是用补码来表示的,下面用原码来初始化,试试结果对不对, -2的原码0x80,00,00,02
uint a1 = 0x80000002; int a = (int)a1; Console.WriteLine($"{Convert.ToString(a, 2).PadLeft(32, '0')}, {a}");
运行结果
2) 下面使用补码来初始化int变量,-2的补码0xff,ff,ff,fe
下面这么写会报语法错误
int a = 0xfffffffe;
需要这么写
int a = BitConverter.ToInt32(new byte[] { 0xfe, 0xff, 0xff, 0xff }, 0); //或者 uint a1 = 0xfffffffe; int b = (int)a1; Console.WriteLine($"{Convert.ToString(a, 2).PadLeft(32, '0')}, {a}"); Console.WriteLine($"{Convert.ToString(b, 2).PadLeft(32, '0')}, {b}");
运行结果
关于int的最小值的二进制表示
int的最小值int.MinValue为-2147483648
原码: 0x80,00,00,00
反码(除符号位外取反): 0xff,ff,ff,ff
补码(反码+1,符号位不变): 0x80,00,00,00或(0b1000,0000,0000,0000,0000,0000,0000,0000)
根据补码获得反码和原码
static void GetCode(uint complementCode, out uint reverseCode, out uint originCode) { uint signBit = complementCode & 0x80000000; if (0 == signBit) //正数 { reverseCode = complementCode; originCode = complementCode; Console.WriteLine($"{Convert.ToString(reverseCode, 2).PadLeft(32, '0')} 反码"); Console.WriteLine($"{Convert.ToString(originCode, 2).PadLeft(32, '0')} 原码"); } else { uint temp = complementCode; temp -= 1; //补码减1 Console.WriteLine($"{Convert.ToString(temp, 2).PadLeft(32, '0')} (补码-1)"); reverseCode = temp | signBit; Console.WriteLine($"{Convert.ToString(reverseCode, 2).PadLeft(32, '0')} 反码"); temp = ~temp; Console.WriteLine($"{Convert.ToString(temp, 2).PadLeft(32, '0')} (再取反)"); originCode = temp | signBit; Console.WriteLine($"{Convert.ToString(originCode, 2).PadLeft(32, '0')} 原码"); } Console.WriteLine(); }
运行后:
static void Main(string[] args) { uint a = 0; uint b = 0; uint temp = 0x80000000; GetCode(temp, out a, out b); temp = 0x80000001; GetCode(temp, out a, out b); Console.ReadLine(); }
运行结果:
参考
(29条消息) 补码的加减法运算_不去上课的博客-CSDN博客_补码加法