java学习总结(16.05.17)对数据类型取值范围和数据溢出的理解(以byte类型为例)

来源:互联网 发布:2017淘宝双十一攻略 编辑:程序博客网 时间:2024/06/05 11:37

阅读本文前请务必先将原信息码,的反码,补码弄懂

首先,数据类型的储存范围满足这样一条式子:-2^(n-1)~2^(n-1)-1,其中n是该数据类型在内存中所占位数,如byte类型在内存中占用一个字节即8位,其取值范围是-128~127。-128~127总共有2^8=256个数,正好是8个位所有的状态数。那么问题来了,byte类型中为什么负数的范围比正数多出一个数,而多出的-128如何表示。

在解决这个疑问之前,必须先说一下0的表示。在某种意义上,0是一个很特殊的整数。它既不为正也不为负,且+0= -0。我们来看一下正负0的原码反码补码。

——————————————————————————————————————————————————

+0          原码【0000 0000】反码【0000 0000】      补码【0000 0000】

-0           原码【1000 0000】反码【1111 1111】        补码【0000 0000】

——————————————————————————————————————————————————

+0, -0的补码是一样的,但0没有正负的概念,因此,只需用【0000 0000】(原码)来表示0即可。而1~127和-1~-127可用【0000 0001】~【0111 1111】(原码)和【1000 0001】~【1111 1111】(原码)表示。如此一来【1000 0000】(原码)就剩下来了。其实,【1000 0000】就是用来表示-128的。

我们再来看一下-128这个数。

原码【1 1000 0000】     反码【1 0111 1111】     补码【1 1000 0000】

byte类型占用一个字节,只有8个位。这时候,补码中的高位将被截去,即-128的原码和补码都为【1000 0000】,【1000 0000】是原先-0的原码,因为0只需用+0表示就可以了,这个位置就可以用来表示-128了。又因为-128和正负0的补码不同,因此用【1000 0000】表示-128时计算机在计算过程中并不会出现冲突。如此一来-128~127这256个数就可以在一个字节上完整地表示出来。其他整型数据类型的范围问题同理。


关于数据溢出,当类型的运算超出类型的取值范围,便会出现数据溢出。数据溢出得到的结果往往不是我们想要的。下面继续以byte类型为例来进行讨论。

下面举两个例子:

byte(5+125)

5    原码【0000 0101】   反码 【0000 0101】   补码【0000 0101】

125  原码【0111 1101】  反码【0111 1101】    补码【0111 1101】

130=5+125   补码【1000 0010】   反码【1000 0001】   原码【1111 1110】

5和125的补码相加为【1000 0010】 130超出了非符号位的表示范围,因此符号位被改变了,【1000 0010】对应的原码为【1111 1110】,这是-126对应的原码。

因此byte(125+5)的值为-126


注:计算机里数据的运算是通过数据对应的补码进行的,将运算后的出的补码转化成对应原码,而原码对应的数就是运算的结果,如此得出的结果与数本身的运算结果是一致的。但如果出现了数据溢出,补码的符号位就会改变,从而不能得出我们想要的结果。

1 0
原创粉丝点击