二进制深度思考

本文最后更新于:a year ago

之前也写过一些有关于二进制的文章,但总感觉有一些地方没有真正了解其意义。备考期间,仔细查阅了一些资料,这里记录一下。

关于负数底层为什么是取反加一

在实现硬件的加减乘除时,每一个运算用的是一套逻辑运算规则。

目的就是为了使正负相加时,得出正确的结果,所以采用了负数取反加一的策略。

 

1
2
3
4
5
6
// 输出二进制
public static void print(int num){
for(int i = 31; i > 0; i--){
System.out.print((num & (i<<32)) == 0 ? "0" : "1");
}
}

 

 

5 --> 0000 0101

-5--> 1111 1011

 

4 --> 0000 0100

-4 --> 1111 1100

--> 0000 0100

 

1111 1011

0000 0101

 

 

 

 

tips: 补码真正的含义是 模 - 原码的绝对值

补码--让减法操作转变为加法操作,节省硬件成本

 

 

根据数论中模的性质,运算器采用模的性质将减法采用加法实现

例如 原码 0010 1011 有符号数表示 43 无符号数表示 43

1
1010 1011  有符号数表示 -43  无符号数表示 171

 

如果按照真值的算法来计算,43+(-43) = 0(0000 0000)

但按正常的原码来计算的话,0010 1011 (43)

1
2
+1010 1011  (-43)
=1101 0110 (-86)

 

可以发现这样计算根本不可能实现我们的需求

 

而我们的需求是

1
2
3
 0010 1011
-0010 1011
=0000 0000

 

此时就需要我们采用模的原理了,具体可以自己查阅资料

对于8bit为一个存储单元的的计算机来讲,计算时溢出的数,就自动去除了,所以计算机自动实现了mod(模)2的⑧次方。

根据模的性质,模-原码绝对值 = 原码的补数

1,0000 0000 - 0010 1011(-43原码的绝对值) = 1101 0101

而此时你会发现,所得的补数就是补码

而此时的计算就是

1
2
3
   0010 1011
+1101 0101
=1,0000 0000

此时只有8位存数,那么结果也就是 0000 0000

 

采用模运算实现减法,可以大大减少硬件的开发成本,底层实现加法和实现减法难度师大的不一样的

 

至于补码的取法取反加一,根据模的性质

1
2
3
 0010 1011(-43的绝对值)
+1101 0100(取反)
=1111 1111

而1111 1111 + 1 =1,0000 0000

是不是就可以解释为什么补码是取反加1

注意在计算补码时 符号位是不变,这里我们是通过模的性质来计算的,所以是-43的绝对值。

 

所以总的来讲,补码的原意是根据模的性质来的,而补码的意义是为了使硬件不必实现硬件减法仅仅通过加法来实现逻辑上的减法

 

 

 


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!