为什么float4个字节比long8个字节所表示的数值范围广

在Java语言中,我们知道基本数据类型包括数值型、字符型以及布尔型。其中数值型包括整数类型(byte、short、int、long)和浮点类型(float、double)。long型占用8个字节的存储空间,即64bit,最左边一位是符号位,0表示正,1表示负,其余23位存储数值,所以long型可以表示的数值范围为-263到263-1。这个很好理解,而float型占用4个字节,即32bit,所表示的数值范围为-3.403E38到3.403E38,这个数值范围是要大于long型所表示的数值范围的。为什么会这样呢?要搞懂这个问题,就先要明白float型是如何存储的。

float型的存储方式


为了方便说明,这里用单精度浮点数定义的一张图。


其中,左边第一位为符号位,0表示正,1表示负。上图中sign为0,所以为正数。

中间8bit表示指数,但是这里和byte不同,byte型也是8bit,表示的数值范围是-27到27-1,即-128到127。这里exponent的8bit表示的则是-127到128。在IEEE 754(IEEE二进制浮点数算术标准)[2]中规定,在指数的实际值上要加上一个固定的值,目的是为了方便浮点数的计算,该固定值为2e-1-1,其中e表示存储指数的bit的长度。在单精度浮点数中,e的值为8,所以固定值是127。所以,exponent中存储的数值是0(-127+127)到255(128+127),共256个数。在上图中,指数部分存储的是01111100,转换为十进制是124,124减去127(加的固定值)即为实际指数值,即-3。

在小数部分中,最左侧省略了一个1,上图中的小数部分为01,其实就是1.01(二进制),转换为十进制就是1+2-2(这里看不懂的话去复习二进制小数转十进制)。
所以,最终上图所表示的数值为(-1)sign ×\times× fraction ×\times× 2exponent = (+1) ×\times× (1 + 2-2) ×\times× 2-3 = 0.15625。

不过还没有结束,关于浮点数其实还分为零、非规约形式,规约形式、无穷以及NaN,以4字节单精度浮点数为例,具体如下:

形式 指数 小数部分
零   0(实际-127)0
非规约形式 0(实际-126) 大于0小于1
规约形式 1到254(实际-126到127)大于等于1小于2
无穷  255(实际128)非0
NaN 255(实际128) 非0

   
规约形式的浮点数就是指数大于0小于等于2e-2(e为8时值为254),fraction最高位省略了1。“规约”就是指用唯一确定的浮点形式去表示一个值。

如果指数部分的值为0(实际-126,为什么不是0-固定值127 = -127?因为IEEE 754规定非规约形式的浮点数的指数偏移值比规约形式的浮点数的指数偏移值小1),小数部分不为0,那么这个浮点数就是非规约形式的浮点数,这个时候最高位省略的就不是1了,而是0了,所以小数部分是大于0小于1的。所有的非规约浮点数比规约浮点数更加接近0。

下面列出了单精度浮点数各种极值的情况:


我们常说的float型的表示范围其实说的是单精度浮点数最大的规约数的范围。

为什么float4个字节比long8个字节所表示的数值范围还大?


回到这个问题,我想你已经有答案了。
就是float型它有指数部分,规约数的指数可以表示到2127,差不多是1038这么大。再扯远一点,从信息论的角度看,我们有额外的信息(IEEE 754的编码格式规定)嵌入在了数值范围的表示中,即我们知道哪个是符号位,哪些是指数部分,哪些是小数部分,以及省略的最高位的1,所以float型32个bit才能存下这么多信息。
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值