负数的二进制表示及原码、反码、补码的相关知识介绍

前言:

今天在看Collections集合类源码中的二分查找的时候,看到了“>>>”符合,并结合“>>”,想做些总结,顺便复习下原码、反码、补码与负数的二进制表示等相关知识。


概念:

“>>>”:无符号右移(不区分正负数,高位补0)

“>>”  :带符号右移(正数高位补0,负数高位补1)

带符号左移的概念也就清楚了,值得注意的是,没有无符号左移运算符“<<<”!

原码:

正数:正数的原码就是其绝对值的二进制表示

负数:负数的原码就是其绝对值的二进制表示,然后高位补1

例如:-1 的原码是 10000000 00000000 00000000 00000001

          -2 的原码是 10000000 00000000 00000000 00000010

反码:

正数:正数的反码与原码相同

负数:负数的反码等于其原码除符号位以外的各位按位取反

例如:-1 的反码是 11111111 11111111 11111111 11111110

          -2 的反码是 11111111 11111111 11111111 11111101

补码:

正数:正数的补码与原码相同

负数:负数的补码等于其反码的最低位加1

例如:-1 的补码是 11111111 11111111 11111111 11111111

          -2 的补码是 11111111 11111111 11111111 11111110

注意:二进制计算机中的数字表示用的均是补码



为什么需要补码?

在这里,我们用几个简单的计算来说明:

由于正数的原码、反码、补码都是一样的,下面我们只讨论负数的计算,比如我们要计算:1-1

原码计算:

1 - 1

= 00000000 00000000 00000000 00000001 + 10000000 00000000 00000000 00000001

= 10000000 00000000 00000000 00000010 = -3(10),有问题!

反码计算:

1 - 1

= 00000000 00000000 00000000 00000001 + 11111111 11111111 11111111 11111110

= 11111111 11111111 11111111 11111111

= 10000000 0000000 0000000 0000000(其原码)= - 0(10),有问题!问题在如何区分+0和-0上,因为在人的计算概念中,0是没有正负之分的。

补码计算:

1 - 1

= 00000000 00000000 00000000 00000001 + 11111111 11111111 11111111 11111111

= 00000000 00000000 00000000 00000000 = 0(10),正确!

是不是很神奇!



理解了以上的概念和运算后,我们就可以理解位移运算符了

我们还是以例子来说明,比如说我们用5和-5做说明:

“>>”:

5>>1 = 00000000 00000000 00000000 00000101 >> 1

        = 00000000 00000000 00000000 00000010

        = 2(10)

-5>>1 = 100000000 00000000 00000000 000000101(原码)>>1

          = 11111111 11111111 11111111 11111010(反码)>>1

          = 11111111 11111111 11111111 11111011(补码)>>1

          = 11111111 11111111 11111111 11111101(补码结果)

          = -3(10)

同样的

-4>>1 = 10000000 00000000 00000000 00000100 >>1

          = 11111111 11111111 11111111 11111011 >>1

          = 11111111 11111111 11111111 11111100>>1

          = 11111111 11111111 11111111 11111110

          = -2(10)

有的人可能会对“补码求10进制数”的过程有些疑惑,

比如对= 11111111 11111111 11111111 11111101(补码结果)

          = -3(10)——为什么是-3?

其实我们倒回去运算,将其转化为原码就好了(对补码再求一次补码)

11111111 11111111 11111111 11111101(补码)

= 10000000 00000000 00000000 00000010(反码)

= 10000000 00000000 00000000 00000011(补码的补码,即原码)

= -3(10)

又或者换另外一种说法,就是已知一个十进制数的补码x,如何求这个十进制数y呢?(由于正数的补码与原码一致,这里的讨论均是讨论该十进制数为负数的情况)

有个公式大家可以参考下:

y = -(!x + 1)

其实也就是求补码的数学表示,可以解释如下:

十进制负数 = 该十进制负数的二进制数按位取反后加1的相反数(有点绕口...)

不过,对于计算来说还是很好用的!

对于无符号右移(“>>>”),其运算规则跟“>>”一致,但是高位需补0!

比如:

-4>>>1

= 10000000 00000000 00000000 00000100 >>1

= 11111111 11111111 11111111 11111011 >>1

= 11111111 11111111 11111111 11111100 >>1

= 01111111 11111111 11111111 11111110

= 2147483646

验证一番:


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 负数的二进制表示方法 假设有一个 int 类型的数,值为3,那么,我们知道它在计算机中表示为: 00000000 ...
    diveinljq阅读 1,816评论 0 0
  • 我们已经知道计算机中,所有数据最终都是使用二进制数表达。我们也已经学会如何将一个10进制数如何转换为二进制数以及如...
    FantJ阅读 36,983评论 9 29
  • 假设有一个 int 类型的数,值为5,那么,我们知道它在计算机中表示为:00000000 00000000 000...
    子喻爱吃黄焖鸡阅读 526评论 0 0
  • 1.你自已决定是否需要有正负: 就像我们必须决定某个量使用整数还是实数,使用多大的范围数一样,我们必须自已决定某个...
    Xiho丶阅读 2,154评论 0 2
  • 相信看过Friends的朋友们都知道,吃货Joey从来都是拒绝与别人分享自己的食物的,即使对方是心仪的女生。我嘛,...
    Giselle_R阅读 1,158评论 4 0