补码复习

正数和负数的补码区别

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博客_补码加法

 

posted @ 2022-11-19 22:02  yanghui01  阅读(230)  评论(0编辑  收藏  举报