开发工具分享
  • 首页
  • 计算科学
  • 文化旅游
  • 项目和网站
    • OSSEZ 计算技术
    • USRealEstate 社区
    • 地区文化
    • CWIKI.US
    • BUG.OSSEZ.COM
    • RSS.OSSEZ.COM
CWIKIUS.CN
一个有独立思考和温度的清新站
  1. Home
  2. Computer Science
  3. This article

Java 中的 NaN

2021年09月24日 645Browse 0Like 0Comments

概述

简单来说可以认为 NaN 是一个数字数据类型变量值,这个类型变量被定义为 这不是一个数字。

在这篇文章中,我们对 Java 中的 NaN 进行一些简单的描述和说明和在那些操作的过程中可以尝试这个值,和可以如何去避免。

什么是 NaN

NaN 通常表示一个无效的操作结果。 例如,你尝试将数字 0 去除以 0,这个在数学中是不存在的,同时在 Java 中定义 NaN 也确实就是通过这个不存在的操作来定义的。

我们通常也使用 NaN 来表示不能显示的变量值。 例如,我们对数字 -1 开平方根的时候,也是这种情况。

例如我们可以只在负数的情况下描述 value (i) 。

在页面 IEEE 754 - 维基百科,自由的百科全书 中对非数值 NaN 的定义进行了说明。你可以阅读上面的文章来了解更多有关 NaN 的定义。

在 Java 中,只有浮点数据类型 float 和 double 实现了这个标准。

Java 咋 使用 Float.NaN 和Double.NaN 来定义了 NaN 构造函数。

 

nan-c-01

 

在 double 中一个常量 Not-a-Number (NaN) 定义了这个值,这个值等于 Double.longBitsToDouble(0x7ff8000000000000L) 的返回值。

和

在 float 中一个常量 Not-a-Number (NaN) 定义了这个值,这个值等于 Float.intBitsToFloat(0x7fc00000) 的返回值。

在 Java 中没有针对其他数据类型定义的 NaN 了。

NaN 的比较

在 Java 中,如果我们开始写一个方法的时候,我们应该需要针对方法的输入数据进行检查,以确保输入数据的准确和输入数据在允许的范围内。

NaN 在绝大部分情况下都不是一个有效的输入参数,因此在 Java 的方法中,我需要对输入的参数进行比较,以确保输入的参数中的值不是 NaN,然后我们能够对输入参数进行正确的处理。

NaN 不能余任何浮点类型数据进行比较,这就表示,任何有 NaN 参与的比较都会返回 false(这里只有一个例外为 “!=” 将会返回 true)。

我们将会得到 针对 x != x 表达式,如果 x 是 NaN 的话,我们将会在这里得到 true。

考察下面的代码:

System.out.println("NaN == 1 = " + (NAN == 1));
System.out.println("NaN > 1 = " + (NAN > 1));
System.out.println("NaN < 1 = " + (NAN < 1));
System.out.println("NaN != 1 = " + (NAN != 1));
System.out.println("NaN == NaN = " + (NAN == NAN));
System.out.println("NaN > NaN = " + (NAN > NAN));
System.out.println("NaN < NaN = " + (NAN < NAN));
System.out.println("NaN != NaN = " + (NAN != NAN));

下面的内容就是针对上面代码的输出结果。

NaN == 1 = false
NaN > 1 = false
NaN < 1 = false
NaN != 1 = true
NaN == NaN = false
NaN > NaN = false
NaN < NaN = false
NaN != NaN = true

所以,我们不能够通过比较来检查数据是不是 NaN。

事实上,我们也不应该用 “==” 或 “!= “ 来对 double 或者 flat 类型的数据进行比较。

所以,我们可以使用 “x != x”* 表达式来检查 NaN 是不是为 true。

更多的,我们可能会使用 Float.isNaN 和Double.isNaN 方法来检查这个输入的参数值是不是 NaN。
实际上,这种方法更好,因为这能够让代码更加易读。

考察下面的代码:

double x = 1;
System.out.println(x + " is NaN = " + (x != x));
System.out.println(x + " is NaN = " + (Double.isNaN(x)));
        
x = Double.NaN;
System.out.println(x + " is NaN = " + (x != x));
System.out.println(x + " is NaN = " + (Double.isNaN(x)));

下面内容就是上面代码的输出。

1.0 is NaN = false
1.0 is NaN = false
NaN is NaN = true
NaN is NaN = true

产生 NaN 的操作

当我们对 float 和 double 类型进行操作和计算的时候,我们应该注意某些操作是可能会产生 NaN 值的。

一些针对浮点计算的方法和操作是会产生 NaN 这个值来替换掉可能抛出的异常,换句话说就是有些操作不会抛出异常,但是返回的结果是 NaN。

最常见的情况就是对数字进行计算的时候,这个算法在数学中还没有被定义,或者被定义是不可以这样做的。
如最常见的 0 除以 0 的情况。

因为在数学中,这种情况被定义为非法的。

        System.out.println("Undefined Operations Produce NaN");
        final double ZERO = 0;
        System.out.println("ZERO / ZERO = " + (ZERO / ZERO));
        System.out.println("INFINITY - INFINITY = " + (Double.POSITIVE_INFINITY - Double.POSITIVE_INFINITY));
        System.out.println("INFINITY * ZERO = " + (Double.POSITIVE_INFINITY * ZERO));
        System.out.println();

上面的代码将会有下面的输出:

Undefined Operations Produce NaN
ZERO / ZERO = NaN
INFINITY - INFINITY = NaN
INFINITY * ZERO = NaN

同时有关数字的操作和计算的结果并不能产生数字的情况下也会输出为 NaN。

        System.out.println("Operations with no real results produce NaN");
        System.out.println("SQUARE ROOT OF -1 = " + Math.sqrt(-1));
        System.out.println("LOG OF -1 = " + Math.log(-1));
        System.out.println();

上面的代码的结果如下:

Operations with no real results produce NaN
SQUARE ROOT OF -1 = NaN
LOG OF -1 = NaN

所有数字与有 NaN 参与的计算的结果也会返回 NaN:

        System.out.println("Operations with NaN produce NaN");
        System.out.println("2 + NaN = " + (2 + Double.NaN));
        System.out.println("2 - NaN = " + (2 - Double.NaN));
        System.out.println("2 * NaN = " + (2 * Double.NaN));
        System.out.println("2 / NaN = " + (2 / Double.NaN));
        System.out.println();

上面的diam将会输出为:

Operations with NaN produce NaN
2 + NaN = NaN
2 - NaN = NaN
2 * NaN = NaN
2 / NaN = NaN

最后,我们知道我们不能够给 double 或者 float 指派为 null 对象类型。

作为另外一种解决方案,我们可以为 double 或者 float 指派 NaN 数值来表示丢失或者未知的值:

如下面的代码:

double maxValue = Double.NaN;

结论

在本篇文章中,我们对 NaN 的情况进行了一些简单的讨论,同时我们也讨论了在实际的计算中可能会有哪些情况会导致产生 NaN,同时对如何进行 NaN 在 Java 中的比较和计算也提供了一些实例。

欢迎大家参与讨论。

 

https://www.ossez.com/t/java-nan/13748

Tags: None
Last updated:2021年09月24日

HoneyMoose

有温度的人文和独立的思考

Like
< Previous
Next >

Comments

Cancel reply

Archives
  • May 2026
  • April 2026
  • March 2026
  • February 2026
  • January 2026
  • December 2025
  • November 2025
  • October 2025
  • September 2025
  • August 2025
  • July 2025
  • June 2025
  • May 2025
  • April 2025
  • March 2025
  • February 2025
  • January 2025
  • December 2024
  • November 2024
  • October 2024
  • September 2024
  • August 2024
  • July 2024
  • June 2024
  • May 2024
  • April 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • September 2023
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • April 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022
  • August 2022
  • May 2022
  • April 2022
  • March 2022
  • February 2022
  • January 2022
  • December 2021
  • November 2021
  • October 2021
  • September 2021
  • August 2021
  • July 2021
  • June 2021
  • May 2021
  • April 2021
  • March 2021
  • February 2021
  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • September 2019
  • August 2019
  • July 2019
  • June 2019
  • May 2019
  • April 2019
  • March 2019
  • February 2019
  • January 2019
  • December 2018
  • November 2018
  • October 2018
  • September 2018
  • August 2018
  • July 2018
  • June 2018
  • May 2018
  • April 2018
  • March 2018
Categories
  • Computer Science (2,362)
    • Confluence (663)
    • Gradle (12)
  • U.S. (482)
  • 文化旅游 (145)

COPYRIGHT © 2020 CWIKIUS. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

湘ICP备2020018253号-1