【Java】Java中的NAN解析

今天在学习集合框架的时候,看源码发现了一个不是很理解的问题(Float源码):

    /**
     * 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.
     */

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

判断isNan为什么是v != v ,what???这不是判断两个float是否相等么?

我们仔细看一下上面的注释:

如果指定的参数(float v入参)是NAN,返回true,否则就是false
NAN :Not-a-Number(不是一个数字)

从上面我们可以分析出来:意思就是两个NaN用==比较的结果会得到false。

校验一下:

float firstNan=Float.NaN;
float secoenNan=Float.NaN;
System.out.println("firstNan!=secoenNan = "+(firstNan!=secoenNan));


打印的结果:
firstNan!=secoenNan = true

到底什么是NAN?我们查阅一下资料,维基百科上得到如下的结果:

 

有点晦涩,下面我们具体讲解一下

1、什么是NAN?

简单地说,NaN是一个数字数据类型值,代表“不是数字”。NAN通常表示无效操作的结果,Java将floatdouble类型的NaN常量定义为Float .NaN和Double.NaN

“ 持有类型为double的非数字(NaN)值的常量。它相当于Double.longBitsToDouble(0x7ff8000000000000L)返回的值。”

“保持float类型的非数字(NaN)值的常量。它等同于Float.intBitsToFloat(0x7fc00000)返回的值。”

我们猜一下下面的结果:

运行代码:

System.out.println("0 / 0 = " + (0 / 0));

是的,你猜对了ArithmeticException

输出结果:

Exception in thread "main" java.lang.ArithmeticException: / by zero
	at com.test.BaseTest.main(BaseTest.java:25)

现在猜猜输:

运行代码

System.out.println("0.0 / 0.0 = " + (0.0 / 0.0));

猜对了吗?

0.0 / 0.0 = NaN

double和float所有的,对于Java中的其他数值数据类型,我们没有这种类型的常量。

2、NAN的校验与比较

在java中编写代码时,我们应该注意检查输入是否有效且在预期范围内。在大多数情况下,NaN值不是有效输入。因此,我们应该验证输入值不是NaN值并适当地处理这些输入值。

NaN无法与任何浮动类型值进行比较。这意味着我们会得到虚假的涉及所有的比较操作的NaN(除“!=”为此我们得到真正的)。

测试代码如下

float Nan = Float.NaN;
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值,我们可以使用:Float.isNaNDouble.isNaN方法来检查这些值,这种方法易读易懂。、

3、isNan()和isInfinite()的区别

NaN:非数值类型;

Infinite:无穷大(包含正无穷大、负无穷大);

总结:

在Java的计算中,在执行涉及float和double类型的操作时,可能会产生NaN值。一些浮点方法和操作产生NaN值而不是抛出异常。我们可能需要明确处理这些结果,我们可以使用:Float.isNaNDouble.isNaN方法来检查;

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 可以使用数学表达式解析库来验证公式是否书写正确,例如使用 Apache Commons Math 库的 ExpressionParser 类。下面是一个简单的示例: ```java import org.apache.commons.math3.analysis.function.Exp; import org.apache.commons.math3.analysis.function.Sin; import org.apache.commons.math3.analysis.function.Sqrt; import org.apache.commons.math3.analysis.function.Tan; import org.apache.commons.math3.analysis.parser.Expression; import org.apache.commons.math3.analysis.parser.ExpressionParser; public class FormulaValidator { public static boolean validate(String formula) { ExpressionParser parser = new ExpressionParser(); Expression expression = parser.parse(formula); double x = 1.0; // 可以设置变量的值进行计算验证 double result = expression.evaluate(x); return !Double.isNaN(result) && !Double.isInfinite(result); // 判断计算结果是否合法 } public static void main(String[] args) { String formula1 = "sin(x) + cos(x)"; // 正确的公式 String formula2 = "sqrt(x) - 2"; // 错误的公式,sqrt 函数参数不能为负数 String formula3 = "tan(x) / (1 - cos(x))"; // 错误的公式,除数不能为 0 System.out.println(validate(formula1)); // true System.out.println(validate(formula2)); // false System.out.println(validate(formula3)); // false } } ``` 在上面的示例,我们使用了数学表达式解析的 ExpressionParser 类来解析公式,并且可以通过 evaluate 方法计算公式的值。在计算之前,我们可以设置变量的值进行验证,例如上面示例的 x 变量。最后,我们还需要判断计算结果是否合法,例如不能为 NaN 或 Infinity。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值