float类型表示方式及范围深度解析

float类型的值以4个字节表示,共32bit,根据IEEE754标准,float类型使用1位做符号位,8位做指数位,23位做尾数位,格式如下:
在这里插入图片描述
整个浮点数可表示为: f = s × t × 2 i f = s \times t \times 2^{i} f=s×t×2i,其中 s s s为符号位-1或1, t t t为尾数, i i i为指数

下面将三个部分分别进行介绍

符号位:

0表示正,1表示负

指数部分:

指数位用8位移码表示。8bit可表示256个数,用移码可表示的十进制范围为-127~128,将指数位的移码为0表示浮点数的指数为负无穷,整个浮点数为0;当指数的移码为255时表示指数为正无穷,浮点数为最大值。所以实际用来表示的移码范围为 1 ~ 254 ,转换成十进制原码为 -126 ~ 127,也就是整个指数部分(注意:只算指数部分)所能表示的最小的正数值为 2 − 126 2^{-126} 2126,最大的值为 2 127 2^{127} 2127。如图所示:在这里插入图片描述

尾数部分:

尾数部分部分共23位,表示范围为0 ~ 2 23 − 1 2^{23}-1 2231。在规约式浮点数的尾数部分中小数点前还隐藏着一个固定的整数值整数1,尾数部分的23位只用来表示小数点后的值,这种方式可保证浮点数有唯一的表示形式。规约式浮点数尾数部分如图所示:
规约式浮点数的尾数部分

最小绝对值分析

对于规约式浮点数可表示的最小的正数为 2 − 126 2^{-126} 2126,我们可用代码来验证:

    public static void main(final String[] args) throws InterruptedException
    {
		
        BigDecimal b1 = new BigDecimal("0.5");
        System.out.println(b1.pow(126).floatValue()); //2的-126次方的浮点数值
        System.out.println(Float.MIN_NORMAL);//浮点数的最小规格化正数
    }

输出结果表明float的最小规约化正数为 2 − 126 2^{-126} 2126
在这里插入图片描述
当正数值小于 2 − 126 2^{-126} 2126时,指数部分将变成-127,根据前面的指数部分的介绍,此时的浮点数应为0,我们使用代码来验证发现并不是0:


    public static void main(final String[] args) throws InterruptedException
    {
        BigDecimal b1 = new BigDecimal("0.5");
        System.out.println(b1.pow(126).floatValue());
        System.out.println(b1.pow(127).floatValue());
    }

运行截图:
在这里插入图片描述
这是因为float类型采用了渐进式下溢出,当float类型的数小于 2 − 126 2^{-126} 2126次方时将不继续采用规约式表示,而改为非规约式表示,所谓非规约式表示也就是摆脱了小数点前必须为1的限制,对于小于 2 − 126 2^{-126} 2126的数小数点前可以为0。采用渐进式下溢出的原因是,如果不采用0与绝对值最小的浮点数之间距离将大于两个相邻浮点数之间的距离,且前者是后者的 2 23 2^{23} 223倍!!!(绝对值最小的规约式浮点数之前计算出为 2 − 126 2^{-126} 2126,与0的距离为 2 − 126 2^{-126} 2126,倒数第二小的值为 ( 1 + 2 − 23 ) × 2 − 126 = 2 − 126 + 2 − 149 (1+2^{-23}) \times 2^{-126}=2^{-126}+2^{-149} (1+223)×2126=2126+2149,与 2 − 126 2^{-126} 2126的距离为 2 − 149 2^{-149} 2149

当采用了渐进式下溢出,float类型所能表示的绝对值最小的数便为: 2 − 149 2^{-149} 2149,可用代码验证:


    public static void main(final String[] args) throws InterruptedException
    {
        BigDecimal b1 = new BigDecimal("0.5");
        System.out.println(b1.pow(149).floatValue());
        System.out.println(Float.MIN_VALUE);
    }

运行结果为:
在这里插入图片描述
当浮点数的绝对值小于 2 − 149 2^{-149} 2149时,则彻底超出了float所表示的最小绝对值,将会被表示成0。我们来验证一下 2 − 150 2^{-150} 2150

    public static void main(final String[] args) throws InterruptedException
    {
        BigDecimal b1 = new BigDecimal("0.5");
        System.out.println(b1.pow(150).floatValue());
    }

运行结果为:
在这里插入图片描述
综上所述,float类型的最小绝对值数为: 2 − 149 2^{-149} 2149

最大绝对值分析

最大绝对值就比较简单了,当尾数全为1,指数为127时为最大,也就是 ( 2 − 2 − 23 ) × 2 127 (2-2^{-23}) \times 2^{127} (2223)×2127
使用代码来验证下:


    public static void main(final String[] args) throws InterruptedException
    {
        BigDecimal b1 = new BigDecimal("2");
        System.out.println(b1.pow(128).subtract(b1.pow(104)).floatValue());
        System.out.println(Float.MAX_VALUE);
    }

运行结果如下:
在这里插入图片描述
当大于 ( 2 − 2 − 23 ) × 2 127 (2-2^{-23}) \times 2^{127} (2223)×2127时,将显示无穷大:

    public static void main(final String[] args) throws InterruptedException
    {
        BigDecimal b1 = new BigDecimal("2");
        System.out.println(b1.pow(128).add(new BigDecimal(1)).floatValue());

    }

运行结果为:
在这里插入图片描述

参考文献:
https://baike.baidu.com/item/IEEE%20754/3869922?fr=aladdin

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值