Double和Float中的NaN、Infinite等常量字段详解

Double和Float中的NaN、Infinite等常量字段详解

在采用Java进行数值运算,特别是double和float时,经常会遇到需要判断某个数是否为一个数(NaN)、是否为无(Infinite)。一个数都已经是double或者float数据类型的了,为什么还说它不是一个数(Not a Number)呢?这就要从数学上来说了。

对于除法,一个数与另一个数的运算存在以下几种情况:

情形 被除数 除数 结果
1 0 非0 0
2 0 0 非法
3 非0 0 非法
4 非0 非0 非0

显然,在实际的Java数值运算中,以上四种情况都需要考虑到,并且实际使用中也确实是这样的。当遇到情形2以及情形3中除数是整数时,Java会抛出异常java.lang.ArithmeticException: / by zero

当然,以上是初等数学的内容,高等数学中还会有“无穷”这种概念存在。在一般的数学学科中,无穷不是一个数,它是任意大的数,表示一种趋势。但是在实变函数中,无穷却是一个常量。同样的,在Java中,无穷同样不是一个数。

那么在Java中如何表示无穷呢?对于情形3,将被除数改为0.0即可得到无穷大(POSITIVE_INFINITY或者NEGATIVE_INFINITY)。那么无穷小呢?在Double和Float的常量字段值表中并没有无穷下这个常量字段,实际上0.0就代表了无穷下,并且一个数除以0.0是不会抛出异常的。

那么NaN是如何产生的呢?当将一个非数字转换为数字以及有非数字参与数值计算的时候就会产生NaN;另一种情形是,当除数为0或0.0,而被除数为0.0的时候,也会产生NaN。

以下是几种特殊的数值运算:

情形 被除数 除数 结果
1 number 0 ArithmeticException: / by zero
2 0或者0.0 0.0 NaN
3 非0的number 0.0 Infinity或者-Infinity
4 MAX_VALUE MIN_VALUE Infinity

对于这几种情形,如何进行判断呢?

Java中提供了几种方法:

  1. isInfinite() 用于判断一个数是否为无穷大(包括正无穷大与负无穷大),以下为源码实现:
/**
     * Returns {@code true} if the specified number is infinitely
     * large in magnitude, {@code false} otherwise.
     *
     * @param   v   the value to be tested.
     * @return  {@code true} if the value of the argument is positive
     *          infinity or negative infinity; {@code false} otherwise.
     */
public static boolean isInfinite(double v) {
    return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
}
  1. isNaN() 用于判断一个数是否是一个数,如下源码:
/**
     * 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 value of the argument is NaN;
     *          {@code false} otherwise.
     */
public static boolean isNaN(double v) {
    return (v != v);
}
  1. isFinite() 用于判断一个数时候是一个可用的数字,当输入是Infinity时,返回false,如下源码:
/**
     * Returns {@code true} if the argument is a finite floating-point
     * value; returns {@code false} otherwise (for NaN and infinity
     * arguments).
     *
     * @param d the {@code double} value to be tested
     * @return {@code true} if the argument is a finite
     * floating-point value, {@code false} otherwise.
     * @since 1.8
     */
public static boolean isFinite(double d) {
    return Math.abs(d) <= DoubleConsts.MAX_VALUE;
}

注意:isFinite方法是java 8新加入的方法。

猜你喜欢

转载自blog.csdn.net/Subson/article/details/71405427