在学习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. vue—你必须知道的 js数据类型 前端学习 CSS 居中 事件委托和this 让js调试更简单—console AMD && CMD 模式识别课程笔记(一) web攻击 web安全之XSS JSONP && CORS css 定位 react小结

    vue—你必须知道的   目录 更多总结 猛戳这里 属性与方法 语法 计算属性 特殊属性 vue 样式绑定 vue事件处理器 表单控件绑定 父子组件通信 过渡效果 vue经验总结 javascript ...

  2. 前端学习:学习笔记(JS部分)

    前端学习:学习笔记(JS部分) 前端学习:JS学习总结(图解)    JS的简介 JS基本语法 JS内置对象 JS的函数 JS的事件 JS的BOM JS的DOM JS的简介 新建步骤 <body ...

  3. 前端学习(十五):了解 Javascript

    进击のpython ***** 前端学习--了解JavaScript Javascript是一种运行在浏览器中的解释型的编程语言 还记得我们在说python的时候提过解释型和编译型的区别 在解释型语言 ...

  4. 每天成长一点---WEB前端学习入门笔记

    WEB前端学习入门笔记 从今天开始,本人就要学习WEB前端了. 经过老师的建议,说到他每天都会记录下来新的知识点,每天都是在围绕着这些问题来度过,很有必要每天抽出半个小时来写一个知识总结,及时对一天工 ...

  5. web前端学习部落22群分享给需要前端练手项目

    前端学习还是很有趣的,可以较快的上手然后自己开发一些好玩的项目来练手,网上也可以一抓一大把关于前端开发的小项目,可是还是有新手在学习的时候不知道可以做什么,以及怎么做,因此,就整理了一些前端项目教程, ...

  6. 【web前端学习部落22群】分享 碰撞的小球开源小案例

    对于课程中的疑问,大家可以加 web前端学习部落22群 120342833和其他老师还有众多的小伙伴们进行沟通交流哦,群里还有不少技术大拿.行业大牛 可以一起探讨问题,我们也会安排专业的技术老师为大家 ...

  7. web前端学习部落22群开源分享 左边菜单导航

    有大量web前端开发工具及学习资料,可以搜群[ web前端学习部落22群 ]进行下载,遇到学习问题也可以问群内专家以及课程老师哟 <!DOCTYPE html> <html lang ...

  8. 【前端】Web前端学习笔记【2】

    [2016.02.22至今]的学习笔记. 相关博客: Web前端学习笔记[1] 1. this在 JavaScript 中主要有以下五种使用场景 在全局函数调用中,this 绑定全局对象,浏览器环境全 ...

  9. 前端学习 第七弹: Javascript实现图片的延迟加载

    前端学习 第七弹: Javascript实现图片的延迟加载 为了实现图片进入视野范围才开始加载首先: <img    src="" x-src="/acsascas ...

随机推荐

  1. 76、android:supportsRtl 和 android:layout_marginEnd

    android4.2(SDK版本为17)有一个新特性 layoutRtl,当然是对于开发者而言的,主要是方便开发者去支持阿拉伯语/波斯语等阅读习惯是从右往左的. 可以在manifest的applica ...

  2. 多线程sshd爆破程序代码

    不多说了,直接上手代码,也没有啥练手的,都是很熟悉的代码,水一篇,方便作为工作的小工具吧.试了一下,配合一个好点的字典,还是可以作为个人小工具使用的. #!/usr/bin/env python # ...

  3. C# 图片识别技术(支持21种语言,提取图片中的文字)

    图片识别的技术到几天已经很成熟了,只是相关的资料很少,为了方便在此汇总一下(C#实现),方便需要的朋友查阅,也给自己做个记号. 图片识别的用途:很多人用它去破解网站的验证码,用于达到自动刷票或者是批量 ...

  4. 使用Mac App Store更新、下载软件时出现未知错误的解决方法

    很多果迷在使用 Mac App Store 更新/下载软件时,可能都曾被”未知错误”困扰过,怎么解决也不行.然而,过一段时间不知道做了什么又自己好了.今天我们提供两个解决这个问题的方法,下次遇到这个问 ...

  5. 用httpclient做压力测试时Too many open files的解决办法

    在工作过程中,用httpclient去压测一个web api,发现压一小段时间就出现了Too many open files.实际上,HttpClient建立Socket时 ,post.release ...

  6. 解析oracle的rownum,数据库查询结果返回行数设置

    对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数,而且rownum不能以任何表的名称作为前缀 ...

  7. LeetCode 笔记系列十 Suduko

    题目:Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by ...

  8. Piwik网站访问统计软件安装

    Piwik是一个PHP和MySQL的开放源代码的Web统计软件. 它给你一些关于你的网站的实用统计报告,比如网页浏览人数, 访问最多的页面, 搜索引擎关键词等等… Piwik拥有众多不同功能的插件,你 ...

  9. Content-Negotiation Header Quality Values

    HTTP: The Definitive Guide 17.3.2 Content-Negotiation Header Quality Values The HTTP protocol define ...

  10. ubuntu重新设置登陆界面|切换gdm kdm lightdm

    方法: $ sudo dpkg-reconfigure gdm 然后会出一个让你进行选择的提示,根据需要切换即可