用c#语言解释二进制源码和补码

273 阅读3分钟

二进制

我们知道,计算机最终处理的都是0和1的二进制的数据,二进制又分为有符号数和无符号数,今天就带你们详细了解一下。我会以代码为例子让各位更清晰的明白,所用语言为C#语言。

无符号数

所谓无符号数就是没有符号的数,数有正负之分,但是只有负数的时候才会有符号,所以无符号数就是正数。 无符号数不用考虑正负,所以数中的每个二进制数都是用来表示数值的。 下面请看代码:

UInt16 decimals = 2767;
string binary = Convert.ToString(decimals,2);
Response.Write("Data:<span>" + binary + "</span><br/>");
Response.Write("Length:"+binary.Length);

首先我定义一个了一个16位无符号整数的变量decimals,赋值为2767,然后转成二进制形式,并打印了出来,结果如下:

结果

这里大家应该都看得懂,2767这个十进制转成二进制就是上述图片中的二进制数字。

有符号数

所谓有符号数就是有正负的数,可以是负数了,所以在二进制的数字中,我们就拿最高位的数字用来表示正负,0表示正,1表示负。 下面请看代码:

 Int16 decimals = 2767;
 string binary = Convert.ToString(decimals,2);
 Response.Write("Data:<span>" + binary + "</span><br/>");
 Response.Write("Length:"+binary.Length);

这跟上述的唯一区别就是这次我定义的是有符号的16位整数,然后我们接着来输出看看结果。

结果

从表面上看是一样的,实质上是不一样的,第一个是无符号整数,输出的是源码,第二个我们有符号整数,输出的补码。但是由于正数的源码和补码是一样,所以我们看到的是一样的。 这里C#语言给我们省略了4个0,实际上完整的Data应该是:0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1。 最高位就是符号位为0,就是正数。

负数的情况

Int16 decimals = -3;
string binary = Convert.ToString(decimals,2);
Response.Write("Data:<span>" + binary + "</span><br/>");
Response.Write("Length:"+binary.Length);

结果

这里,输出的补码,源码转补码的步骤是:首先是求出3的源码是:1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1

然后把这个源码全部取反,0变1,1变0,符号位不变,变成:1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0,然后在加1得到:1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1得到补码。

说到这里,那补码有什么用呢?

补码是在源码的基础上取反加1,那么想想,比如3-2,就可以改为3+(2的补码),这样就把减法变为了加法,在计算机(cpu)中,是没有减法器,只有加法器,所以补码的存在最大的作用可以把减法变为加法。

这里我们四位来模拟演示:

首先求出3的源码为:0011 然后求出2的补码为:1110

然后0011+1110等于0001,0001转为10进制就为1,这样就把减法转为了加法。

这里加法可能大家会求出10001,前面那个1是符号位的进位,需舍去。

注意,最后求得的0001是补码的形式,由于最高位是0,所以是正数,正数的原码和补码是一样的,所以不用转换为原码。

如果得到的结果最高位是1,那么就是负数,这时候就需要把补码转为原码才能得到结果。