原码 | 反码 | 补码

机器数

1 - 一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的:在计算机用一个数的最高位存放符号,正 0 负 1。比如十进制数 +3,转换成二进制就是 0000 0011;对应的 -3 ,就是 1000 0011。这里的 0000 0011 和 1000 0011 就是机器数

真值

1 - 因为有符号位,所以机器数的形式值就不等于真正的数值。例如有符号数 1000 0011,其真值是 -3 而不是形式值 131

2 - 所以为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。0000 0001 真值是 +000 0001 == +1;  1000 0001 真值是  -000 0001 == -1

原码

1 - 原码就是该整数转换成符号位的二进制数:如 +1 的原码是 0000 0001;  -1 的原码是 1000 0001

反码

1 - 正数的反码是其本身;负数的反码是在其原码的基础上,符号位不变,其余各个位取反。比如  +1 == 0000 0001(原)== 0000 0001(反);  -1 == 1000 0001 (原)== 1111 1110(反)

补码

1 - 正数的补码是其本身;负数的补码是在反码的基础上 +1;比  +1 == 0000 0001(原)== 0000 0001(反)== 0000 0001(补);  -1 == 1000 0001(原)== 1111 1110(反)== 1111 1111(补)

注:这并不是补码的概念,只不过是负数的补码等于其反码 + 1

值溢出

1 - 由于计算机中的数字用补码表示,例如 8 位的 byte 类型的表示范围为:[-128, 127]

    补码和原码、反码不同,没有 +0 和 -0 一说,只有一个 0

    原码、反码存在 +0 和 -0,取值范围 [-127,127]

    比如  0 == 0000 0000(补)    -128 == 1000 0000(补)   127 == 0111 1111(补)

2 - 当 byte 类型的变量超上限 127 时

      128 == 127 + 1 

      == 0111 1111(补)+ 0000 0001(补) 

      == 1000 0000(补) 

      == -128

      129 == 127 + 2 

      == 0111 1111(补)+ 0000 0010(补) 

      == 1000 0001(补) 

      == -127

3 - 当 byte 类型的变量超过下限 -128 时

      -129 == -128 - 1 

        == 1000 0000(补) - 0000 0001(补) 

      == 0111 1111(补) 

      == 127

      -130 == -128 - 2 

        == 1000 0000(补) - 0000 0010(补) 

      == 0111 1110(补) 

      == 126

注:关于补码溢出的问题,可用一张图来描述(以 8 bit 为例)

说明:我们会发现 -128 和 128 补码相同;-127 和 129 补码相同;-130 和 126 补码相同.......你会发现什么 ?

小结:有符号位的情况下

1 - 数字 0:正 0 的原码、反码、补码、都是 0000 0000

     负 0 的原码是 1000 0000、反码是 11111111。注:负 0 没有补码

2 - 补码思想:计算机为何要引入补码

① 先看 2 + (-2)= 0;如果用原码表示则是 0000 0010 + 1000 0010 = 1000 0100,结果是 -4 这显然就扯犊子了。为了解决这个不正经的问题,要使 0000 0010 + ???? ???? = 0 那么问号必定是 1111 1110(这串神秘代码熟悉否?不熟悉也没问题,继续往下瞅),注意:这里问号所代表的这串数字就是 -2 的补码!为什么 ?

③ 以钟表为例 10 - 2 = 8 和 10 + 10 = 20,其实 8 和 20 所表达的意思是一样的,都代表 8 点整!10 点后退 2 小时或前进 10 小时,不就是 8 点么。是的,加上的数字 10 和减去的数字 2 两个加起来刚好等于模(12),这两个数我们称之为同余数,这就是补码思想

④ 我们回到 2 - 2 = 0 这个问题,根据补码思想,2 - 2 其实等价于 2 + (256-2),就是 254(二进制是 1111 1110),我们知道 1111 1110 是 -2 和 254 的补码(整不明白往上看值溢出的示例),同样的这串数字也不就是问号所代表的数字

⑤ 最终我们要的是同余数 254 和 -2 之间的关系 :它们相同的补码 1111 1110(其实就是 254 的原码,只不过符号位溢出了) 如何操作能够变成 -2 的原码 1000 0010 ?不就是补码先减去 1,然后按位取反,至此 OK 啦。注:补码其实就是一个代替负数的正数,这样就使计算机中只存在正数,计算简化且方便

 

posted on   低头捡石頭  阅读(661)  评论(0编辑  收藏  举报

编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示