Java 基础 - 原码,补码和反码

回到顶部(go to top)

总结

1-正数的原码,反码,补码都一致;负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

[+1] = [00000001]原 = [00000001]反 = [00000001]补

[-1] = [10000001]原 = [11111110]反 = [11111111]补

2-结论:机器数存储的是“补码”

 

3-为何机器不用“反码”进行运算? 

为了“尝试”让符号位直接参与加减法运算,引入“反码”。但是很多结果是不对的。

 

3.1 符号位直接参与运算结果不对

想象一个8位数的"-1+3"运算,如果用反码计算 [11111110]反 + [00000011]反,无论符号位参参与运算,结果都很奇怪:

  • 符号位参与运算:   [11111110]反 + [00000011]反 = [00000001]反 = [01111110]原  不等于 2
  • 符号位不参与运算:[11111110]反 + [00000011]反 = [00000001]反 = [0111111]原    不等于 2

 

3.2 +0 -0 的问题

 

 

用反码计算减法, 在"0"这个特殊的数值上. 虽然人们理解上+0和-0是一样的, 但是0带符号是没有任何意义的. 而且会有[0000 0000]和[1000 0000]两个编码表示0.

 

4-为何机器使用“补码”进行运算?

为了解决反码符号位计算的错误,以及+0和-0的问题,引入“补码”

4.1 符号位直接参与运算结果正确

想象一个8位数的"-1+3"运算,如果用补码计算:

-1+3 = [11111111]补 + [00000011]补 = [0000 0010]补 = [0000 0010]原 = 2

 

4.2 +0 -0 的问题

 

 

这样0用[0000 0000]表示, 而以前出现问题的-0则不存在了.而且可以用[1000 0000]表示-128: 

 

-1-127的结果应该是-128, 在用补码运算的结果中, [1000 0000] 就是-128. 但是注意因为实际上是使用以前的-0的补码来表示-128, 所以-128并没有原码和反码表示.(对-128的补码表示[1000 0000]补算出来的原码是[0000 0000], 这是不正确的)

使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数. 这就是为什么8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127].

因为机器使用补码, 所以对于编程中常用到的32位int类型, 可以表示范围是: [-231, 231-1] 因为第一位表示的是符号位.而使用补码表示时又可以多保存一个最小值.

 

 

回到顶部(go to top)

原文链接

原码,补码和反码:https://www.cnblogs.com/wqbin/p/11142873.html

为什么计算机采用补码而不是原码或反码?https://www.zhihu.com/question/352057791

posted on   frank_cui  阅读(254)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2019-01-06 Spring Bean自动检测
2019-01-06 java 自定义注解
< 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

导航

统计

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