C Note 20210618

原码

  • 最高位为符号位,0表示整数,1表示负数。
  • 其他部分就是数值本身绝对值的二进制数。
  • 负数的原码就是绝对值基础上,最高位变1。
    十进制 原码
    +40 0010 1000
    -40 1010 1000
    +0 0000 0000
    -0 1000 0000

原码的问题

  • 表示方法简单易懂
  • 加减运算的时候不方便,需要比较绝对值
0010 1001  //41  
0010 1000  //40  
0000 0001  //1  
//无问题  
0010 1000  //40  
0010 1001  //41  
0000 0001  //1  
//无法确定结果的正负,需要先比较绝对值

反码

  • 正数处理与原码相同。
  • 负数处理,符号位不变,其他部分取反。
    十进制 反码
    +40 0010 1000
    -40 1101 0111
    +0 0000 0000
    -0 1111 1111

反码Test

0010 1001  //+41   
1101 0111  //-40  
0000 0000  //溢出部分被丢弃,我他妈直接归零?

反码的问题

不是很理解,姑且先把别人的结论抄上来:

这里我们可以知道 -0 对应的原码是 1000 0000,而 +0 对应的原码是 0000 0000。虽然 -0 和 +0 代表的数值是一样的,但是在用原码和反码表示时它们是不同的。通过以上的多个示例,我们发现使用反码进行加法运算并不能保证得出正确的结果。原因是用一个字节表示数字的取值范围时,这些数字中多了一个 -0。为了解决反码出现的问题,就出现了补码。

补码

  • 正数的处理,原、反、补码都是一致的。
  • 负数的处理,补码为反码的+1
  • 符号位不动,其他位取反,然后+1得到原码。
    十进制 补码
    +40 0010 1000
    -40 1101 1000
    +0 0000 0000
    -0 0000 0000

补码Test

0010 1001  //+41  
1101 1000  //-40  
0000 0001  //超出的部分被舍弃,得出正确结果(符号位进位被舍弃)  

补码解决了什么

  • 符号位也被纳入运算。
  • 统一了0的编码问题。
  • 让减法可以转换为加法。

总结

  • 补码的出现让电路设计变得方便,只需要加法器和补码器就可以完成。
  • 以前一直觉得只是补码之类的,只是单纯的数学问题,现在从电路设计的角度上感受到了它的意义。
  • 听前辈说补码是C语言里非常重要的一部分,需要理解它才能解决很多问题,但目前还不知道这些问题是什么,还是没认知到。

参考

Avatar photo 心有所向,日复一日,必有精进。 Twitter Tweet