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

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

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

情形被除数除数结果
10非00
200非法
3非00非法
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是不会抛出异常的。

6c945a76391a4734a30b03fc06964ff2.jpg

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

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

情形被除数除数结果
1number0ArithmeticException: / by zero
20或者0.00.0NaN
3非0的number0.0Infinity或者-Infinity
4MAX_VALUEMIN_VALUEInfinity

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

Java中提供了几种方法:

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);
}

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);
}

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新加入的方法。

未经允许请勿转载:程序喵 » Double和Float中的NaN、Infinite等常量字段详解

点  赞 (0) 打  赏
分享到: