偏移二进制编码和二进制补码的区别

一、二进制补码

在计算机系统中,数值一律用补码来表示和存储,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。

正整数的补码和源码相同;

0的补码是0;

负数的补码是符号位不变,原码的各位取反,再加1。

1 1000 0000            1111 1111    ……    1000 0001        0000 0000        0000 0001    ……    0111 1111
    -2^n            -2^n-1        ……        -1                0                1        ……        2^n-1

1 0111 1111+1        1000 0000+1    ……    1111 1110+1        0000 0000        0000 0001    ……    0111 1111
1 1000 0000            1000 0001        1111 1111

负数补码表示的范围比原码稍宽,对于整数,范围是:-2^n~2^n-1

 以下参考:https://blog.csdn.net/qq_29545231/article/details/78622927

在32位机中定义signed short a =0xeeee;

执行printf(“%d\n”,a),printf(“0x%x\n”,a)的结果分别是什么呢?

signed short a = 0xeeee;

printf("%d\n",a);
printf("0x%x\n",a);

结果:

-4370
0xffffeeee

 0xeeee=1110 1110 1110 1110,是有符号short型,在计算机中,负数是以补码形式存储的,即:符号位不变,原码各位取反加一。

现在已知负数在计算机中的存储的数值(所以变量初始化时用的十六进制,就直接初始化成补码了啊),再求这个值,顺序就反了,先减一再按位取反:

1110 1110 1110 1110——减1——>1110 1110 1110 1101——按位取反——>1001 0001 0001 0010,最高位1是负数,001 0001 0001 0010是4370,所以值为4370。

 

但是在32位机中,使用printf函数进行输出时都会进行类型隐式转换,转换为4字节的类型。

有符号类型(signed char)无论向有符号类型(int)还是无符号类型(unsigned int)转换,都会按照有符号数的转换规则(高位补符号位)。

无符号类型(unsigned char)无论向有符号类型(int)还是无符号类型(unsigned int)转换,都会按照无符号数的转换规则(高位补0)。

 0xeeee是有符号位,高位补1,所以打印输出为:0xffffeeee

若0xeeee非要输出16位,可把变量强制转化:

printf("0x%x\n",(unsigned short)a);

输出结果:

0xeeee

上面的强制转化只为了打印显示,实际值大小变了。

所以对于二进制补码形式的编码,正负过渡不方便时,可以直接用十进制数来过渡。

二、偏移二进制码

把补码的符号位取反就是偏移二进制码。

如16位的数,0x0000是-32768,0x8000是0,0xFFFF是32767,偏移二进制码用十六进制时正负过渡比较方便

posted @ 2019-11-28 10:23  我是二狗  阅读(11605)  评论(0编辑  收藏  举报