浮点数在内存中的表现形式, Infinity和NaN的出现情况及特点(通俗解释)

浮点数在内存中的表现形式, Infinity和NaN的出现情况及特点(通俗解释)

(本着通俗易懂来解释,其中很多概念并没有说到,如有错误,欢迎指正,感谢!)

首先看代码

 public static void main(String[] args) {

 //     System.out.println(12%0);           / by zero

        System.out.println(10 % 0.0);        // NaN
        System.out.println(1.2 % 0);        // NaN
        System.out.println(1.2 % 0.0);      // NaN

        System.out.println("============================");

 //     System.out.println(12 / 0);               / by zero

        System.out.println(1.2 / 0.0);          // Infinity
        System.out.println(1.2 / 0);          // Infinity
        System.out.println(1.2 / 0.0);          // Infinity

    }

为什么这些浮点数运算中,操作数为含有0时,并没有抛出异常,而是打印出Infinity与 NaN, 这两个又是什么?


  • 查看Java源码
    1. Float中
public static final float POSITIVE_INFINITY = 1.0F / 0.0;   //正无穷大
public static final float NEGATIVE_INFINITY = -1.0F / 0.0;  //负无穷大
public static final float NaN = 0.0F / 0.0;    //非数

2.Double中

public static final double POSITIVE_INFINITY = 1.0D / 0.0;   //正无穷大
public static final double NEGATIVE_INFINITY = -1.0D / 0.0;   //正无穷小
public static final double NaN = 0.0D / 0.0;     //非数

其中确实定义了Infinity与NaN



浮点数在计算机中内部的表现形式

数字是无限的,内存空间是有限的

  • 浮点数在计算机中遵循IEEE 754标准

计算机内部是无法精确表示浮点数的。

 System.out.printf("%.17f",(0.1+0.2));  // 输出: 0.30000000000000004

根据标准,浮点数在计算机内部存储原理:
float(32位)为例

符号位区域指数位区域小数位区域
1位8位23位
  • 浮点数在计算机内部中的表示,被分为三个区域:
    符号位区域(31),指数位区域(30-23),小数位区域(22-0)

  • 指数区域的数值是偏移过的数值 =  “真正的指数位 + 偏移量” 的编码方式
  • 偏移量是为了表达负数设计的
  • float类型的偏移量默认为127


内部二进制转换成原始浮点数公式

实际数字 = (-1)符号位值 × 2指数位值-127  × 1.小数位值 

假设浮点数是: 3.14

对应的二进制为:11.00100011110101110000000(也许有效位过长后面还有,但小数位只有23位,到这里结束,将之后的舍入,舍入也有对应的规则)

换算成科学计数法为: 1.10010001111010111000000 × 2 1
真正的指数为:1
偏移过的指数为:1+127=128   真指数经过偏移值进行偏移

正数,符号位区域为:1
偏移过的指数在指数位区域表示: 10000000
尾数区域表示: 10010001111010111000000


所以整个表示为: 0 10000000 10010001111010111000000

通过上述公式,可以将二进制数还原
运算过程结果为:
 (−1)0×​10(10000000 − 01111111)​×​1.10010001110101110000000
= 1×​21×​1.5696868896484375
= 3.139373779296875‬

与3.14相比很明显出现偏差



IEEE 754标准中规定

  1. 如果指数位区域全为1(255),且小数位为0(0),根据符号位表示正无穷大或负无穷大(+/- Infinity)
  • 当0.0作为为除数 或者 浮点数除0就会出现这种情况

  1. 如果指数位区域全位1,且小数位不为0,这个数表示为不是一个数(NaN)
  • 取余运算中0.0作为后者 或者 浮点数%0时会出现该情况

浮点数表现形式参考网址: 浮点数表现形式


Infinity特点

  • 无限乘以0=NaN
  • 无限除以无限=NaN
  • 除了这两个操作,其它对无限的操作结果都是无限

NaN特点:

  • NaN表示非数(不是数),包括它自身在内。
  • 任何没有良好定义浮点运算,结果都为NaN
  • 对负数求平方根,结果为NaN
  • 任何运算中只要含有NaN,则结果为NaN
  • NaN用在关系表达式中,整个表达式结果为false


    更多详解:
    百度百科–IEE 754
    https://zhuanlan.zhihu.com/p/89320102

参考资料:
https://zhuanlan.zhihu.com/p/89320102
( 注:部分资料参考网络,如有侵权请联系。)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值