Java什么时候能产生NaN?

时间:2021-02-27 23:02:07

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

我知道什么是Java Double。南。我有一些生成NaN的Java代码。

// calculate errors
delta = m1 + m2 - M;
eta = f1 + f2 - F;
for (int i = 0; i < numChildren; i++) {
  epsilon[i] = p[i]*m1+(1-p[i])*m2+q[i]*f1+(1-q[i])*f2-C[i];
}

// use errors in gradient descent
// set aside differences for the p's and q's
float mDiff = m1 - m2;
float fDiff = f1 - f2;
// first update m's and f's
m1 -= rate*delta;
m2 -= rate*delta;
f1 -= rate*eta;
f2 -= rate*eta;
for (int i = 0; i < numChildren; i++) {
  m1 -= rate*epsilon[i]*p[i];
  m2 -= rate*epsilon[i]*(1-p[i]);
  f1 -= rate*epsilon[i]*q[i];
  f2 -= rate*epsilon[i]*(1-q[i]);
}
// now update the p's and q's
for (int i = 0; i < numChildren; i++) {
  p[i] -= rate*epsilon[i]*mDiff;
  q[i] -= rate*epsilon[i]*fDiff;  
}

Under what circumstances will Java produce a NaN value?

Java在什么情况下会产生NaN值?

4 个解决方案

#1


3  

Given what I know about gradient descent, you are most probably jumping out to infinity because you do not have adaptive rate (i.e. your rate is too big).

根据我对梯度下降的了解,你很可能会跳到无穷大,因为你没有适应性速率(也就是说你的速率太大)。

#2


33  

NaN is triggered by the following occurrences:

NaN由以下事件触发:

  • results that are complex values
    • √x where x is negative
    • √x,x是负的
    • log(x) where x is negative
    • log(x) x是负的
    • tan(x) where x mod 180 is 90
    • tan(x) x乘以180等于90
    • asin(x) or acos(x) where x is outside [-1..1]
    • asin(x)或acos(x),其中x在[-1..1]
  • 结果是复杂的价值观√x x -日志(x),x - tan(x)x国防部180等于90最佳(x)或治疗(x)其中x是外(1 . . 1)
  • 0/0
  • 0/0
  • ∞/∞
  • ∞/∞
  • ∞/−∞
  • ∞/−∞
  • −∞/∞
  • −∞/∞
  • −∞/−∞
  • −−/∞∞
  • 0×∞
  • 0×∞
  • 0×−∞
  • 0×−∞
  • 1
  • 1∞
  • ∞ + (−∞)
  • ∞+(−∞)
  • (−∞) + ∞
  • (−∞)+∞

Sorry for such a general answer, but I hope that helped.

很抱歉这么笼统的回答,但我希望能有所帮助。

#3


4  

According to Wikipedia:

根据*:

There are three kinds of operation which return NaN:

有三种类型的操作返回NaN:

  • Operations with a NaN as at least one operand
  • 使用NaN作为至少一个操作数的操作
  • Indeterminate forms
    • The divisions 0/0, ∞/∞, ∞/−∞, −∞/∞, and −∞/−∞
    • 0/0的分歧,∞/∞∞/−∞,−∞/∞,和−∞/−∞
    • The multiplications 0×∞ and 0×−∞
    • 乘法0×∞和0×−∞
    • The power 1
    • 电源1∞
    • The additions ∞ + (−∞), (−∞) + ∞ and equivalent subtractions.
    • 添加∞+(−∞),(−∞)+∞和删除工作。
  • 不定形成部门0/0,∞/∞∞/−∞,−∞/∞,和−∞/−∞乘法0×∞和0×−∞1∞∞增加+力量(−∞),(−∞)+∞和删除工作。
  • 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)
    • 切的一个奇怪的多个90度(或π/ 2弧度)
    • The inverse sine or cosine of a number which is less than −1 or greater than +1.
    • 反正弦或余弦的数量大于或小于−1 + 1。
  • 实际操作与复杂的结果:一个负数的平方根负数的对数切一个奇怪的多个90度(或π/ 2弧度)的反正弦或余弦大于或小于−1 + 1。

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

此Java代码片段说明了上述所有内容,除了切线(我怀疑是因为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.)

    如果任意一个操作数为NaN,则==的结果为false,而!=的结果为true。事实上,测试x !=x为真,当且仅当x的值为NaN。(浮动的方法。isNaN和双。isNaN也可以用来测试一个值是否为NaN。

#4


0  

Have you tried sprinkling your code with System.out.println statements to determine exactly where NaNs start occuring?

你有没有试过用System.out来喷洒你的代码。println语句来确定NaNs开始出现的确切位置?

#1


3  

Given what I know about gradient descent, you are most probably jumping out to infinity because you do not have adaptive rate (i.e. your rate is too big).

根据我对梯度下降的了解,你很可能会跳到无穷大,因为你没有适应性速率(也就是说你的速率太大)。

#2


33  

NaN is triggered by the following occurrences:

NaN由以下事件触发:

  • results that are complex values
    • √x where x is negative
    • √x,x是负的
    • log(x) where x is negative
    • log(x) x是负的
    • tan(x) where x mod 180 is 90
    • tan(x) x乘以180等于90
    • asin(x) or acos(x) where x is outside [-1..1]
    • asin(x)或acos(x),其中x在[-1..1]
  • 结果是复杂的价值观√x x -日志(x),x - tan(x)x国防部180等于90最佳(x)或治疗(x)其中x是外(1 . . 1)
  • 0/0
  • 0/0
  • ∞/∞
  • ∞/∞
  • ∞/−∞
  • ∞/−∞
  • −∞/∞
  • −∞/∞
  • −∞/−∞
  • −−/∞∞
  • 0×∞
  • 0×∞
  • 0×−∞
  • 0×−∞
  • 1
  • 1∞
  • ∞ + (−∞)
  • ∞+(−∞)
  • (−∞) + ∞
  • (−∞)+∞

Sorry for such a general answer, but I hope that helped.

很抱歉这么笼统的回答,但我希望能有所帮助。

#3


4  

According to Wikipedia:

根据*:

There are three kinds of operation which return NaN:

有三种类型的操作返回NaN:

  • Operations with a NaN as at least one operand
  • 使用NaN作为至少一个操作数的操作
  • Indeterminate forms
    • The divisions 0/0, ∞/∞, ∞/−∞, −∞/∞, and −∞/−∞
    • 0/0的分歧,∞/∞∞/−∞,−∞/∞,和−∞/−∞
    • The multiplications 0×∞ and 0×−∞
    • 乘法0×∞和0×−∞
    • The power 1
    • 电源1∞
    • The additions ∞ + (−∞), (−∞) + ∞ and equivalent subtractions.
    • 添加∞+(−∞),(−∞)+∞和删除工作。
  • 不定形成部门0/0,∞/∞∞/−∞,−∞/∞,和−∞/−∞乘法0×∞和0×−∞1∞∞增加+力量(−∞),(−∞)+∞和删除工作。
  • 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)
    • 切的一个奇怪的多个90度(或π/ 2弧度)
    • The inverse sine or cosine of a number which is less than −1 or greater than +1.
    • 反正弦或余弦的数量大于或小于−1 + 1。
  • 实际操作与复杂的结果:一个负数的平方根负数的对数切一个奇怪的多个90度(或π/ 2弧度)的反正弦或余弦大于或小于−1 + 1。

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

此Java代码片段说明了上述所有内容,除了切线(我怀疑是因为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.)

    如果任意一个操作数为NaN,则==的结果为false,而!=的结果为true。事实上,测试x !=x为真,当且仅当x的值为NaN。(浮动的方法。isNaN和双。isNaN也可以用来测试一个值是否为NaN。

#4


0  

Have you tried sprinkling your code with System.out.println statements to determine exactly where NaNs start occuring?

你有没有试过用System.out来喷洒你的代码。println语句来确定NaNs开始出现的确切位置?