原码、反码、补码和位运算

参考:

https://www.zhihu.com/question/20159860

https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html

总结一些要点

为了使计算机运算数据更加简单,减法转换为加法: 1 - 1 => 1 + (-1)。为了支持这个功能,计算机对数据的存储需要一些额外的处理。

原码:最高位作为符号位,也就是对于1和-1的区别,只是最高位不一样。

反码:正数的反码和原码是一致的,而负数,除了最高位是1,其余位取反。

补码:正数的补码和原码是一致的,而负数的补码是负数的反码+1,+1之后可能会触发进位,导致最高位由1变成0,这种情况下所有位都是0了,也就是数字的值为0,因为0没有正负之分,所以可以认为补码表示法中,计算机认为最高位是1的都是负数,其余都是正数或者0

计算机采用补码的编码方式来存储数字,如以4位的数字长度表示 3 + (-3):

3的补码 = 3的原码 = 0011

-3的补码 = -3的反码(1100) + 1 = 1101

0011 + 1101 = 10000,因为这里数字位为4,超出的被丢弃掉,所以运算结果是0000 = 0

根据补码的规律,计算出实际的数值,如 

1010 0000 0000 0000 0000 0000 0000 0000     -1之后

1001 1111  1111 1111  1111  1111  1111  1111    再除了最高外之外的位取反

1110 0000 0000 0000 0000 0000 0000 0000   ,除了符号位之后,其他位就是实际的正数数值了,复制到计算器中:

正数对应值为 1610612736  ,所以上面补码对应的值是 -1610612736

位运算

value >> n :数字补码右移n位,最高位保持不变,如4位长度的数字:1010(-6)右移1位成1101(-3),0111(7)右移1位成0011(3)

value << n:数字补码左移n位,最低位补0,左移过程中最高位会发生变化,数字的正负可能会颠倒,以上面的-1610612736 演示一下这个过程:

对应的补码是:1010 0000 0000 0000 0000 0000 0000 0000,左移动1位之后 0100 0000 0000 0000 0000 0000 0000 0000  对应的数值:

 程序运行,结果一致:

 所以左移不能简单理解为就是 乘以2 ,否则程序容易出bug。

value >>> n:与上面的右移,多了一个>,区别在于最高位不是保持不变了,而是固定补0,也就意味着,对于负数来说,右移补0之后,就变成正数了。

猜你喜欢

转载自www.cnblogs.com/hellohello/p/11881258.html