无符号编码和补码编码的区别

原码反码补码

**原码:**一个数的原码(原始的二进制码)有如下特点:

  • 最高位做为符号位,0表示正,为1表示负
  • 其它数值部分就是数值本身绝对值的二进制数
  • 负数的原码是在其绝对值的基础上,最高位变为1

**反码:**对于正数,反码与原码相同;对于负数,符号位不变,其它部分取反(1变0,0变1)

注:反码运算也不方便,通常用来作为求补码的中间过渡。

补码:

在计算机系统中,数值一律用补码来存储。

补码特点:

  1. 对于正数,原码、反码、补码相同
  2. 对于负数,其补码为它的反码加1
  3. 符号位不动,源码其他位求反,最后整个数加1,得到补码
无符号数编码

对向量$\vec{x}=[ x_{w-1},x_{w-1}, . . . ,x_{1},x_{0}] $无符号编码使用的是原码进行编码
B 2 U ω ( x ⃗ ) = ∑ i = 0 w − 1 x i 2 i B2U_ω(\vec{x})=\sum_{i=0}^{w-1}x_i2^i B2Uω(x )=i=0w1xi2i
函数 B 2 U ω ( x ⃗ ) B2U_ω(\vec{x}) B2Uω(x )将一个长度为 w w w的0、1串向量映射到非负整数来编码无符号数

补码编码

对向量$\vec{x}=[ x_{w-1},x_{w-1}, . . . ,x_{1},x_{0}] $
B 2 T ω ( x ⃗ ) = − x w − 1 2 w − 1 + ∑ i = 0 w − 1 x i 2 i B2T_ω(\vec{x})=-x_{w-1}2^{w-1}+\sum_{i=0}^{w-1}x_i2^i B2Tω(x )=xw12w1+i=0w1xi2i
最高位 x w − 1 x_{w-1} xw1也称符号位,权重值为 − 2 w − 1 -2^{w-1} 2w1,是符号位,当其值被设置为1,则为负数,设置为0时,值为非负, B 2 T ω B2T_ω B2Tω是一个双射函数,也意味着每一个数的补码只对应一个编码,而每一个编码也唯一对应一个数。

补码转换为无符号数

对于满足 T M i n w ≤ x ≤ T M a x w TMin_w≤x≤TMax_w TMinwxTMaxw x x x有:
KaTeX parse error: No such environment: equation at position 8: \begin{̲e̲q̲u̲a̲t̲i̲o̲n̲}̲ T2U_w(x)=\left…
比如,我们看到 T 2 U 16 ( − 12345 ) = − 12345 + 2 16 = 53191 T2U_{16}(-12345)=-12345+2^{16}=53191 T2U16(12345)=12345+216=53191,同时 T 2 U 16 ( − 1 ) = − 1 + 2 16 = U M a x w T2U_{16}(-1)=-1+2^{16}=UMax_w T2U161=1+216=UMaxw B 2 U ω ( x ⃗ ) 和 B 2 T ω ( x ⃗ ) B2U_ω(\vec{x})和 B2T_ω(\vec{x}) B2Uω(x )B2Tω(x )的差,从0到 w − 2 w-2 w2位将相互抵消,剩下一个值 B 2 U ω ( x ⃗ ) 和 − B 2 T ω ( x ⃗ ) = x + x w − 1 ( 2 w − 1 − ( − 2 w − 1 ) ) = x w − 1 2 w B2U_ω(\vec{x})和-B2T_ω(\vec{x})=x+x_{w-1}(2^{w-1}-(-2^{w-1}))=x_{w-1}2^w B2Uω(x )B2Tω(x )=x+xw1(2w1(2w1))=xw12w既可得到 B 2 U ω ( x ⃗ ) = x w − 1 2 w + B 2 T ω ( x ⃗ ) B2U_ω(\vec{x})=x_{w-1}2^w+ B2T_ω(\vec{x}) B2Uω(x )=xw12w+B2Tω(x )

扩展一个数字的位表示

short int 转换为int 需要转换数据的字长确要同时保证值不变,这就需要进行扩展数字的位操作了

​ 无符号数的扩展是通过往拓展位置加0,而不码数的扩展则是向扩展位中加符号位,我们可以看下面一段代码

#include <stdio.h>

typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, size_t len)
{
    size_t i;
    printf("0x");
    for (i = len-1; i < len; i--)
        printf("%.2x", start[i]);
    printf("\n");
}
int main()
{
    short sx =-12345;
    unsigned short usx=sx;
    int x=sx;
    unsigned ux=usx;
    printf("sx=%d:\t",sx);
    show_bytes((byte_pointer)&sx,sizeof(short));
    printf("usx=%u:\t",usx);
    show_bytes((byte_pointer)&usx,sizeof(unsigned short));
    printf("x=%d:\t",x);
    show_bytes((byte_pointer)&x,sizeof(int));
    printf("ux=%u:\t",ux);
    show_bytes((byte_pointer)&ux,sizeof(unsigned int));
    return 0;
}

image-20210514134245223

​ 从这段代码的运行结果可以看出-12345的补码和53191表示在16位字长的值是相同的,而使用补码扩展时则会将扩展位置为1(负数的符号为1),无符号编码时则将扩展位置为0。

END

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值