8位存储-128引发的思考(伯纳乌的流浪猫)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

学习中会遇到一些看似简单的问题,但是问题后面会引发多个疑问,一点一滴的积累才是最重要的;

不能够把简单问题彻底弄清楚,也就成不了高手,问大家两个简单问题:

计算机中为什么采用补码才存储数据?为什么8位二进制可以表示-128?

如果你能够在几秒钟内说出原因,那证明你的看书看的很仔细,如果不能够准确答出,那就要跟着我一起来回顾

刚上大学时学过的知识了,温故而知新这个道理其实很深奥。

原因:

1. 原码的不足:0的二异性,+0的原码= 00000000(8位来算);-0的原码:10000000;

2. 用原码进行四则运算时,符号位需要单独处理,且运算规则复杂;

3. CPU中,一个最小的运算单元(三极管)就是一个与非门,所有的运算加、减、乘除都要转换成与非运算,

每次与非运算都要是耗时间的,采用补码,进行与非运算的次数会最小,提高运算效率;使用原码会提高使用寄存器的次数,效率差;

4. 负数采用补码之后,可以使加减统一为加法运算;使符号位能与有效值部分一起参加运算,从而简化运算规则;

正是由于上述原码的不足,促使人们去寻找更好的存储方式:补码。

补码思想的一个好例子:

时钟问题:假如准确时间为6点,现在时间是8点,那么顺时针拨10个小时和逆时针拨3个小时的效果是一样的;

即(8 - 2) = (8 + 10) mod 12;在模运算中,一个数减去另一个数,可以转化为一个数加上另一个数的补数。

注:

正数的原码= 正数的补码= 正数的反码

负数的反码,除了最高位符号位不变,其他位取反;

负数的补码,除了最高位符号位不变,其他位取反,并在末位加1;

补码转为为原码:

如果补码为正数,则原码为其本身;

如果补码为负数,则除符号位,各位取反,末位加1;

1 + (-1) = 0;

但是从原码角度来计算:

0000 0001

+1000 0001

----------

1000 0010

结果为-2,显然不正确,证明用原码来计算是存在错误的。

其实,我们可以得到8位负数的补码,-1的补码为0xff,-2的补码为0xfe, ... ,-127的补码为1000 0001;

我们发现一个规律:补码随着负增值的变大,反而越来越小,到-127时变为1000 0001,那么我们可以很快得出-128的补码为:1000 0000;即用-0来表示-128;

负数的补码随着负数的增长而变小这个规律是正确的,因为我们把值还原的话,正是在补码的基础上求反再加1;从而可以得到-1的补码0xff还原之后,除去符号位,变成了除了-0之外,最小的数1;而-128的补码0x00还原之后,得到的原码为:1 0000 0000,除去溢出的符号位,正好为0。

举例1(8位计算):

-1 + 3 = 2:

-1原码:1000 0001

-1反码:1111 1110

-1补码:1111 1111

即:0xff

3原码:0000 0011

3补码:0000 0011

-1 + 3表示:

+0000 0011

-----------

10000 0010

高位溢出,最后结果为0000 0010,转化为原码为正数+2,结果正确。

举例2(8位计算)

-2 - 3 = -5:

-2补码:1111 1110

-3补码:1111 1101

1111 1110

+1111 1101

-----------

11111 1011

高位溢出,得出结果为:1111 1011,再转化为原码为:10000101,结果为-5,正确。

深度挖掘:

char类型的范围为-128~127,占8位;

8位二进制数的原码和反码表示不了-128,只能表示-127~+127之间的数:

-127: 1111 1111

127: 0111 1111

只有补码才能表示-128:

-127 - 1 = -128

-127补码:1000 0001

-1补码:1111 1111

-127 - 1:

1000 0001

+1111 1111

-----------

11000 0000

高位舍去得:1000 0000,转化为原码为:1111 1111 + 1 = 1 0000 0000;

因为+0和-0都是0,有重复,所以在八位二进制中就把-0当作最小数-128用;

即1000 0000;

记住:在八位二进制中,为了区分+0和-0的区别,就把-0当作最小数-128用,即1000 0000;那么-129至少需要9位才能存下来,因为没有一个特定的像-0这种特例来表示它,所以-128很幸运

可以用8位来存储。

-128 - 1 = -129:

1000 0000

+1111 1111

-----------

10111 1111

高位截取后变成了正数,很奇怪吧?结果为0x7f;

那首次溢出结果为0的数是哪一个呢?

答案是-256.

原因:

-255补码为:1 0000 0001

-1补码为:1111 1111

相加结果为10 0000 0000,溢出后截断低8位得:0000 0000,原码为0.

很有意思吧?

相关文档
最新文档