When can Java produce a NaN?

前端 未结 4 1809
太阳男子
太阳男子 2020-12-20 15:33

I know what Java Double.NaN is. I have some Java code that produces NaN.

// calculate errors
delta = m1 + m2 - M;
eta = f1 + f2          


        
4条回答
  •  有刺的猬
    2020-12-20 16:11

    According to Wikipedia:

    There are three kinds of operation which return NaN:

    • Operations with a NaN as at least one operand
    • Indeterminate forms
      • The divisions 0/0, ∞/∞, ∞/−∞, −∞/∞, and −∞/−∞
      • The multiplications 0×∞ and 0×−∞
      • The power 1
      • The additions ∞ + (−∞), (−∞) + ∞ and equivalent subtractions.
    • Real operations with complex results:
      • The square root of a negative number
      • The logarithm of a negative number
      • The tangent of an odd multiple of 90 degrees (or π/2 radians)
      • The inverse sine or cosine of a number which is less than −1 or greater than +1.

    This Java snippet illustrates all of the above, except the tangent one (I suspect because of limited precision of double):

    import java.util.*;
    import static java.lang.Double.NaN;
    import static java.lang.Double.POSITIVE_INFINITY;
    import static java.lang.Double.NEGATIVE_INFINITY;
    
    public class NaN {
        public static void main(String args[]) {
            double[] allNaNs = {
                0D/0D,
                POSITIVE_INFINITY / POSITIVE_INFINITY,
                POSITIVE_INFINITY / NEGATIVE_INFINITY,
                NEGATIVE_INFINITY / POSITIVE_INFINITY,
                NEGATIVE_INFINITY / NEGATIVE_INFINITY,
                0 * POSITIVE_INFINITY,
                0 * NEGATIVE_INFINITY,
                Math.pow(1, POSITIVE_INFINITY),
                POSITIVE_INFINITY + NEGATIVE_INFINITY,
                NEGATIVE_INFINITY + POSITIVE_INFINITY,
                POSITIVE_INFINITY - POSITIVE_INFINITY,
                NEGATIVE_INFINITY - NEGATIVE_INFINITY,
                Math.sqrt(-1),
                Math.log(-1),
                Math.asin(-2),
                Math.acos(+2),
            };
            System.out.println(Arrays.toString(allNaNs));
            // prints "[NaN, NaN...]"
            System.out.println(NaN == NaN); // prints "false"
            System.out.println(Double.isNaN(NaN)); // prints "true"
        }
    }
    

    References

    • Wikipedia/NaN
    • JLS 15.21.1 Numerical Equality Operators == and !=

      If either operand is NaN, then the result of == is false but the result of != is true. Indeed, the test x!=x is true if and only if the value of x is NaN. (The methods Float.isNaN and Double.isNaN may also be used to test whether a value is NaN.)

提交回复
热议问题