原码、反码、补码、移码与大小端数据存储

整数表达方式

原码

原码就是整型的二进制表达。用二进制表示整数也有正负的需要,因此用最高位来表示正负,0为正,1为负。如果都是正数或负数相加不会出现错误,但如果是一正一负相加就会出错了。

1 -> 0000,0001
-1 -> 1000,0001
1+-1 -> 1000,0010 B = -2 D

这个例子可以发现,
当然我们会想,如果直接用原码进行减法计算不就好了?直观的看,当首位表示正负时,符号位不应该参与运算,而是要通过符号位来判定是进行加法还是减法运算。计算机中是没有减法器的,减法器将大大增加芯片设计的复杂度以及成本。同时还要增加电路来识别判断符号位。这会变得很麻烦。
因此思路是如何将减法转换为加法,同时符号位也要直接参与运算。乘法和除法也是可以通过乘法来实现的,因此所有的计算最终都可以通过加法来实现。

反码 1’s Complement

为了解决正负数相加出错的问题,我们可以想到将减数或被减数进行取反操作,因此出现了反码。

1 -> 0000,0001
-1 -> 1000,0001 -> 1111,1110
1+-1 -> 1111,1111 -> 1000,0000 = -0

反码看似解决了整个问题,但又出现了新问题,那就是有了两个零,+0和-0。
实际上反码的唯一作用就是作为求补码的中间步骤。
正数的反码还是原码。
负数的反码为符号位保留,数值位取反。

补码 2’s Complement

为什么会有补码呢?以时钟为例,12小时制的时钟实际上是以12为模的

2 mod 12  = 2
-10 mod 12  = 12-10 =2
14 mod 12 = 2

也就是说当我们想把时钟从6点跳到4点时,可以将时针逆时针回拨2小时,即6-2=4;或者将时钟顺时钟拨10小时,即16%12 =4 。因此a减去b就相当于a加上b的补数,即a-b=a+a补

同余的概念

两个整数a,b若他们除以整数m所得的余数相等,则称a,b对于模m同余。从中我们就可以将减法转换为加法。
一个数的反码+1,实际上是这个数对于它的模的补数,而这个模就是n位二进制所能表示的最大十进制数。
以8为二进制数为例,当超过1111,1111时高位被舍弃,相当于CPU自动对所有二进制数做了2^8取模计算。因此就可以得到补码的计算方式。

补码的计算

  • 正数的补码还是原码
  • 负数的补码为真值取反码后+1
  • 补码逆求码有两种方法
    • 补码-1后取反
    • 补码取反+1

移码

整型排放方法

  • 大端
  • 小端

为什么又大小端存储

大端小端其实不一定有什么好处,知识早期计算机体系设计者的设计方法不同。在实际中两种方式都有在用,特别是TCP/IP数据链路层中对文件的加工传输,编译器中放入内存。

### 原码反码补码移码的定义 #### 定义说明 原码是一种最简单的二进制表示方法,其特点是符号位明确区分正负数。对于正数,符号位为`0`,数值部分直接用二进制表示;而对于负数,符号位为`1`,数值部分同样保持不变[^3]。 反码是对原码的一种转换形式。对于正数而言,反码原码完全一致;而针对负数,则需将其数值部分按位取反得到反码[^2]。 补码进一步改进了反码的形式,在处理负数时更加高效。具体来说,正数的补码即为其本身,而负数的补码可通过对其反码加一获得。 移码主要用于浮点数中的阶码表示,它通过将真值加上一个偏置量来实现无符号化存储。通常情况下,该偏置量等于\(2^{n-1}\),其中\(n\)代表总位数。 --- ### 数值范围分析 #### 原码的数值范围 假设机器字长为 \( n \) 位(含一位符号位),则: - 正数的最大值为 \( (2^{n-1} - 1)_\text{十进制} \) - 负数的最小值为 \( -(2^{n-1} - 1)_\text{十进制} \) 因此,原码能够表示的整数范围为:\[ -(2^{n-1}-1) \sim +(2^{n-1}-1) \][^3] 值得注意的是,存在两个零值分别对应于 `+0` 和 `-0` 的不同编码方式。 #### 反码的数值范围 同理,当考虑 \( n \)-bit 字长时, - 对应正数最大仍可达至 \(+(2^{n-1}-1)\), - 针对负数情况亦可低达 \(-(2^{n-1}-1)\). 所以反码所能覆盖的整体区间同样是:\[-(2^{n-1}-1),+(2^{n-1}-1)\]. 同样地,这里也存在着两种不同的零表达形式(+0,-0)[^4]. #### 补码的数值范围 利用补码体系下, - 最大正值依旧维持在 \(+(2^{n-1}-1)\); - 不过由于引入了一种额外状态用于填补原本由单独 "-0" 占据的位置,使得现在可以达到更低限度直到 \(-2^{n-1}\). 最终得出结论:采用这种机制之后整个可用空间变为连续闭合区域:[\-2^(n−1)..2^(n−1) −1],并且解决了关于双重零表述的问题.[^4] #### 移码的数值范围 考虑到移码实际上是基于补码基础上增加固定偏移量的结果,故此如果原始补码支持从-\(2^{n-1}\)到+\((2^{n-1}-1)\)之间变化的话,那么相应调整后的实际显示效果就会是从0一直到\(2^n-1\). 这意味着每一个可能产生的组合都被赋予了一个独一无二非重复性的呈现形态. 综上所述,给定任意长度N比特的情况下,我们有如下关系成立: \[ [-(2^{n-1})..(2^{n-1}-1)]_{补码} → [(0)..(2^n-1)]_{移码}. \] --- ```python def range_summary(n_bits): max_positive = (2 ** (n_bits - 1)) - 1 min_negative_original_complement = -(2 ** (n_bits - 1)) result = { 'Original Code': f'{-max_positive} to {max_positive}', 'Complementary Code': f'{min_negative_original_complement} to {max_positive}', 'Offset Binary': f'{abs(min_negative_original_complement)} to {(2**n_bits)-1}' } return result print(range_summary(8)) ``` 上述代码展示了如何根据不同编码方案计算并总结它们各自的数值范围。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Weijian Feng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值