在学习Java集合的时候遇到了Float.isNaN(float)函数,点进去一看就不理解了,函数实现如下:

public static boolean isNaN(float v) {
return (v != v);
}

  float的v怎么会不等于自身呢?以下是关于这个函数的描述:

   /**
* Returns {@code true} if the specified number is a
* Not-a-Number (NaN) value, {@code false} otherwise.
*
* @param v the value to be tested.
* @return {@code true} if the argument is NaN;
* {@code false} otherwise.
*/
isNaN()
描述:返回一个 Boolean 值,指明提供的值是否是保留值 NaN (不是数字)。
语法:isNaN(numvalue)numvalue 参数是要检查是否为 NaN 的值。
说明:如果值是 NaN, 那么 isNaN 函数返回 true ,否则返回 false 。

  从上述描述可以知道,这个函数判断一个float参数是不是NaN(Not a Number),即不是一个数字,那么什么是NaN,什么情况下会出现NaN呢?


定义:  

  NaN(Not a Number,非数)是计算机科学中数值数据类型的一个值,表示未定义或不可表示的值。常在浮点数运算中使用。首次引入NaN的是1985年的IEEE 754浮点数标准。

会返回NaN的运算:

  • 操作数中至少有一个是 NaN 的运算
  • 未定义操作
    • 下列除法运算:0/0、∞/∞、∞/−∞、−∞/∞、−∞/−∞
    • 下列乘法运算:0×∞、0×-∞
    • 下列加法运算:∞ + (−∞)、(−∞) + ∞
    • 下列减法运算:∞ - ∞、(−∞) - (−∞)
  • 产生复数结果的实数运算。例如:
    • 对负数进行开方运算
    • 对负数进行对数运算
    • 对比-1小或比+1大的数进行反正弦或反余弦运算

Java中的NaN:

  Java虚拟机在处理浮点数运算时,不会抛出任何运行时异常(这里所讲的是java语言中的异常,请勿与IEEE 754规范中的浮点异常相互混淆,IEEE 754的浮点异常是一种运算信号),当一个操作产生溢出时,将会使用有符号的无穷大来表示,如果某个操作结果没有明确的数学定义的话,将会使用NaN值来表示,所有使用NaN值作为操作数的算术操作,结果都返回NaN。Java中的Double和Float中都有isNaN函数,判断一个数是不是NaN,其实现都是通过上述 v != v 的方式,因为NaN是唯一与自己不相等的值,NaN与任何值都不相等。有些操作会使isNaN返回True,例如:

System.out.println(Float.isNaN(0.0f / 0.0f));
System.out.println(Double.isNaN(Math.sqrt(-1)));

Double的NaN定义:

   /**
* A constant holding a Not-a-Number (NaN) value of type
* {@code double}. It is equivalent to the value returned by
* {@code Double.longBitsToDouble(0x7ff8000000000000L)}.
*/
public static final double NaN = 0.0d / 0.0;

  以上定义了一个常量型的NaN,它的效果和Double.longBitsToDouble(0x7ff8000000000000L)的返回值是一样的,我们可以看看Double.longBitsToDouble中的定义:

If the argument is any value in the range 0x7ff0000000000001L through 0x7fffffffffffffffL or in the range 0xfff0000000000001L through 0xffffffffffffffffL, the result is a NaN. No IEEE 754 floating-point operation provided by Java can distinguish between two NaN values of the same type with different bit patterns.

  如上可知,二进制的0x7ff0000000000001L~0x7fffffffffffffffL 和 0xfff0000000000001L~0xffffffffffffffffL 之间的数值是被定义成NaN类型,类似正无穷大和负无穷大,但又有区别。在Float中也类似。

  总之,在实际数值计算的过程中可能会出现一些非法的操作,导致产生了非法的数值,比如说除零,通过NaN来表示这样一个非数值,NaN与任何浮点数(包括自身)的比较结果都为假,即 (NaN ≠ x) = false,这是NaN独有的特性,所以可以使用与自己相比来确定当前数值是不是一个正常的数。

简单测试:

  @Test
public void NanTest() {
Float f1 = new Float(-1.0 / 0.0);
Float f2 = new Float(0.0 / 0.0);
Double f3 = Math.sqrt(-1); // returns true if this Float value is a Not-a-Number(NaN), else false
System.out.println(f1 + " = " + f1.isNaN());
System.out.println(f2 + " = " + f2.isNaN());
System.out.println(f3 + " = " + f3.isNaN());
System.out.println(Double.isNaN(Double.longBitsToDouble(0x7ff0000000000011L)));
}

再看看这边的解释:Double.NaN != Double.NaN

  还有一点需要注意:在将一个float的NaN窄化转换为整数类型T(T限于int或long类型之一)的时候,那转换结果就是int或long类型的0;而double类型的NaN值将按规定转换为float类型的NaN值。

参考资料:

有趣的NaN类型的更多相关文章

  1. python [吐槽]关于nan类型时遇到的问题

    今天在用写一段求和的代码时候,发现最后返回的是nan的结果,这段循环求和代码依次调用了三个函数,于是依次打印这三个函数的返回值,发现其中一个函数的返回值为nan,原来是因为这段函数里面没有相似的用户, ...

  2. javascript系列:NaN类型

    NaN,即非数值是一个特殊的数值,这个数值用于表示一个本来要返回数值的操作数未返回数值的情况下. ECMAScript中任何数值除以0会返回NaN,因此不影响其他代码运行.   NaN特点:     ...

  3. 【javascript】详解变量,值,类型和宿主对象

    前言 我眼中的<javascript高级程序设计> 和<你不知道的javascript>是这样的:如果<javascript高级程序设计>是本教科书的话, < ...

  4. JavaScript –类型之我晕

    每次写博我觉得取上恬当的题目比整篇行文都难,词量有限的情况下突然想到JavaScript拾遗应该会是一个非常文艺而夺目的博文题目,但我并没有急着使用,经验告诉我应该先去搜一下看有没有被用过.果不其然, ...

  5. MySQL表类型

    学习Mysql数据库,Mysql表类型都有哪些是一定需要知道的,下面就为您介绍七种Mysql表类型,希望能对您学习Mysql表类型有所帮助. MySQL作为当前最为流行的免费数据库服务引擎,已经风靡了 ...

  6. Mysql表的七种引擎类型,InnoDB和MyISAM引擎对比区别总结

    InnoDB和MyISAM区别总结 我用MySQL的时候用的是Navicat for MySQL(Navicat for mysql v9.0.15注册码生成器)操作库.表操作的,默认的表就是Inno ...

  7. MySQL常用的七种表类型(转)

    MySQL常用的七种表类型(转)   其实MySQL提供的表类型截至到今天已经有13种,各有各的好处,但是民间流传的常用的应该是7种,如果再细化出来,基本上就只有两种:InnoDB.MyIASM两种. ...

  8. 深度学习梯度反向传播出现Nan值的原因归类

    症状:前向计算一切正常.梯度反向传播的时候就出现异常,梯度从某一层开始出现Nan值(Nan: Not a number缩写,在numpy中,np.nan != np.nan,是唯一个不等于自身的数). ...

  9. Python中识别DataFrame中的nan

    # 识别python中DataFrame中的nanfor i in pfsj.index: if type(pfsj.loc[i]['WZML']) == float: print('float va ...

随机推荐

  1. php iconv 函数

    原型: $txtContent = iconv("utf-8",'GBK',$txtContent); 特殊参数:iconv("UTF-8","GB2 ...

  2. UI5-文档-2.2-使用SAP Web IDE开发应用程序

    SAP Web IDE是一种基于Web的开发环境,它是为使用最新的创新开发SAPUI5复杂的应用程序.开发和扩展SAP Fiori应用程序.开发移动混合应用程序以及使用插件和模板扩展SAP Web I ...

  3. 递归实现tree JQuery

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  4. webserive学习记录3-eclipse创建webservice

    在用J2EE版的ECLIPSE学习WEBSERVICE的时候发现原来直接用该ECLIPSE就可以创建webservice,然后就自己动手用ECLIPSE自带的功能来建立WEBSERVICE服务端和客户 ...

  5. Haskell语言学习笔记(38)Lens(1)

    Lens Lens是一个接近语言级别的库,使用它可以方便的读取,设置,修改一个大的数据结构中某一部分的值. view, over, set Prelude> :m +Control.Lens P ...

  6. 安装Anaconda以及jupyter的使用

    1)下载https://www.anaconda.com/download/ 2)安装 3)终端查看(Anaconda Prompt) 4)升级所有的包 初次安装下的软件包版本一般都比较老旧,因此提前 ...

  7. MySQL8 重置改root密码及开放远程访问

    1. 修改配置文件 先修改配置文件:vim /etc/my.conf 在 [mysqld] 下加上下面这行 skip-grant-tables 重启 mysql 服务: service mysqld ...

  8. 等待时间,time.sleep()和implicitly_wait()

    在运行一个以前执行的过的功能时,报错了,不能执行了. 功能描述:通过导航,选择下拉项(发布职位功能),下面是审查的元素: 获取元素的代码: 尝试了用xpath去获取:driver.find_eleme ...

  9. hibernate对数据库查询的坑

    hibernate对数据库的查询其实有很多种方法,下面我来介绍我知道的两种方法,以及它们可能会遇到的问题,这里前两种都是查询所有结果 最后一种是 使用hibernate查询一条记录. 第一种方法 pu ...

  10. spotlight

    spotlight - 必应词典 美['spɑt.laɪt]英['spɒt.laɪt] n.聚光灯:聚光灯照亮的地方:聚光灯照明圈:媒体和公众的注意 v.用聚光灯照:突出报道(以使公众注意) 网络射灯 ...