关于java中浮点数中Infinity和NaN的解释

引言

我们都知道计算机是用二进制表示数据,那浮点数计算机是怎么表示的那?

1.0/0的结果是什么?为什么?
0/0的结果是什么?为什么?
0.0/0.0的结果是什么?为什么?

先说结论:

1)1.0/0的结果是什么?为什么?
    1.1 结果:Infinity
    1.2 原因:①1/0.1=10 ②1/0.01=100 ③1/0.001=1000,所以分子确定时,分母越小商越大,分母趋向于0时,商无穷大。对于java语言,手册中也有提到加减运算的第一步就是零值检测,如果涉及其中一个数是0,可以直接得出结果。


2)0/0的结果是什么?为什么?
    2.1 结果:Exception / by zero
    2.2 原因:根据乘法与除法互为逆运算可证,一是零做除数不能得到固定的商;二是零做除数还不回原。因此说:“零做除数没有意义”或“规定零不能做除数”。1)中提到的java语言可适用


3)0.0/0.0的结果是什么?为什么?
    3.1 结果:NaN
    3.2 原因:个人觉得还是java虚拟机自己搞的逻辑,目的就是用一个公式来模拟出这种Not a Number的值来,就像NaN转成Long统一翻译为0xff800001一样。底层应该是在零值检测时处理的。为什么这样说,因为(0.0f == 0)是true,那0.0/0是不是就等于0/0,那为什么会有两种结果。只有自己定义用来标示能解释通的吧。
 

NaN是什么?

        NaN是“IEEE 754”协议中规定了几种特殊值,
        1. 第一种 指数是0并且尾数的小数部分是0,这个数±0(和符号位相关)
        2. 第二种 指数2e-1并且尾数的小数部分是0,这个数是±∞(同样和符号位相关)
        3. 第三种 指数2e-1并且尾数的小数部分非0,这个表示为不是一个数(NaN)
 这些方法也就对应了计算机内部的存储,相对应的就是jdk中native longBitsToDouble()方法中
        <p>If the argument is any value in the range {@code 0x7f800001} through {@code 0x7fffffff} or in the range  {@code 0xff800001} through {@code 0xffffffff}, the result is a NaN.</p>
        <p>If the argument is {@code 0x7f800000}, the result is positive infinity.
        <p>If the argument is {@code 0xff800000}, the result is negative infinity.
        在计算机中归根结底都是要通过0 1来表示,只不过定义的区间不同罢了,java中对NaN用一个Long型值表示 0x7fc00000,具体可参见JDK intBitsToFloat()方法,将一定区间内的值,转化为一个常量值。
 

NaN是怎么产生的?

        NaN的产生还是要通过数学来求证,数学中求这个公式的值x/[x*cos(1/x)],当x趋向于0的时候,利用洛必达法则可推导出这个公式的结果是不存在的,因为cos(1/x)的极限不存在,所以上下不能比较。在代码中乘除的运算都是对应的加减被除数,《码出高效:java开发手册》中提到,加减运算是第一步就是零值检测,检查参加运算是否存在为0的数。

        推测java虚拟机就是在这一步进行的处理,python中使用0.0/0.0会的到一个ZeroDivisionError: float division by zero,并不是NaN,这样表示float('nan')的时候才会提示NaN。

 

触发的情况

      1. 至少有一个参数是NaN的运算
      2. 不定式
            2.1 下列除法运算:0/0、∞/∞、∞/−∞、−∞/∞、−∞/−∞
            2.2 下列乘法运算:0×∞、0×−∞
            2.3 下列加法运算:∞ + (−∞)、(−∞) + ∞
            2.4 下列减法运算:∞ - ∞、(−∞) - (−∞)
      3. 产生复数结果的实数运算。例如:
            3.1 对负数进行开偶次方的运算
            3.2 对负数进行对数运算
            3.3 对正弦或余弦到达域以外的数进行反正弦或反余弦运算

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章