Java 计算信息增益时显示NaN作为输出的双变量数组

Java 计算信息增益时显示NaN作为输出的双变量数组,java,Java,我一直在尝试用Java编写一个程序来计算属性的信息增益,给定它的不同值和所有其他必需值。 下面是我的节目 package dwdmp5; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * * @author Gaurav */ public class Dwdmp5 { /** * @param args the com

我一直在尝试用Java编写一个程序来计算属性的信息增益,给定它的不同值和所有其他必需值。 下面是我的节目

package dwdmp5;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 *
 * @author Gaurav
 */
public class Dwdmp5 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        double P,N,IGtotal;
        System.out.println("How many total P values?");
        P = Double.parseDouble(br.readLine());
        System.out.println("How many total N values?");
        N = Double.parseDouble(br.readLine());
        IGtotal = ((-1)*(P/(P+N))*((Math.log(P/(P+N)))/Math.log(2))) + ((-1)*(N/(P+N))*((Math.log(N/(P+N)))/Math.log(2)));
        System.out.println("Overall Information gain = "+IGtotal);
        int numV;
        System.out.println("How many distinct values of an attribute?");
        numV = Integer.parseInt(br.readLine());
        double [] p = new double[numV];
        double [] n = new double[numV];
        double [] ig = new double[numV];
        int i,temp=0;
        System.out.println("Enter pi for all attributes");
        for(i=0;i<numV;i++)
            p[i] = Integer.parseInt(br.readLine());
        System.out.println("Enter ni for all attributes");
        for(i=0;i<numV;i++)
            n[i] = Integer.parseInt(br.readLine());
        System.out.println("Attribute\tpi\tni\tI(pi,ni)");
        for(i=0;i<numV;i++)
        { temp = i;
         ig[i] = ((-1)*(p[i]/(p[i]+n[i]))*((Math.log(p[i]/(p[i]+n[i])))/Math.log(2))) + ((-1)*(n[i]/(p[i]+n[i]))*((Math.log(n[i]/(p[i]+n[i])))/Math.log(2)));    

         System.out.println("attrib"+(temp+1)+"\t\t"+p[i]+"\t\t"+n[i]+"\t\t"+ig[i]);
        }


    }

}
程序没有显示任何错误。使用科学计算器计算时,相同的值显示正确答案。请帮我解决这个问题

(Java语言规范)规定:

没有数学上确定结果的浮点运算产生NaN

所有以NaN作为操作数的数值运算都会产生NaN作为结果

现在,当您在上阅读JavaDoc时 您将看到:

如果参数为正零或负零,则结果为负无穷大

如果你看一下你的计算,你会发现对于p=4和n=0,你会得到
0.0*Math.log(0.0/(4.0+0.0))
=>
0.0*Math.log(0.0)
=>
0.0*-无穷大
=>
NaN

根据JLS定义的规则,接下来的计算将产生NaN

为什么
0.0*-无限
不等于0?请看这里:

(Java语言规范)说明:

没有数学上确定结果的浮点运算产生NaN

所有以NaN作为操作数的数值运算都会产生NaN作为结果

现在,当您在上阅读JavaDoc时 您将看到:

如果参数为正零或负零,则结果为负无穷大

如果你看一下你的计算,你会发现对于p=4和n=0,你会得到
0.0*Math.log(0.0/(4.0+0.0))
=>
0.0*Math.log(0.0)
=>
0.0*-无穷大
=>
NaN

根据JLS定义的规则,接下来的计算将产生NaN


为什么
0.0*-无限
不等于0?请看这里:

该计算有点复杂,因此我没有彻底检查它(这将是您的工作),但由于您的输入值为4.0和0.0,我猜您在某个点进行了0除法,这将导致NaN(不是数字)。使用调试器查找哪个子表达式导致NaN。任何使用NaN作为操作数的操作都会产生NaN。您的代码有点凌乱,一些空格也可以,但NaN可以被例如除零或类似的情况。刚刚测试了您的计算,似乎您得到了以下情况:
Math.log(n[i]/(p[i]+n[i]))
将有效地导致
-无穷大
,因为
0.0/4.0
将是
0
,因此
Math.log(0)
将是负无穷大。现在,您的计算将执行
-Infinity*0.0
,这将导致
NaN
。在该迭代中,您将得到一个Math.sqrt(0),从而产生NaN。这不会引发异常。该计算有点复杂,因此我没有彻底检查它(这将是您的工作),但由于您的输入值为4.0和0.0,我猜您在某个点进行了0除法,这将导致NaN(不是数字)。使用调试器查找哪个子表达式导致NaN。任何使用NaN作为操作数的操作都会产生NaN。您的代码有点凌乱,一些空格也可以,但NaN可以被例如除零或类似的情况。刚刚测试了您的计算,似乎您得到了以下情况:
Math.log(n[i]/(p[i]+n[i]))
将有效地导致
-无穷大
,因为
0.0/4.0
将是
0
,因此
Math.log(0)
将是负无穷大。现在,您的计算将执行
-Infinity*0.0
,这将导致
NaN
。在该迭代中,您将得到一个Math.sqrt(0),从而产生NaN。这不会引发异常。非常感谢。哥特查塔克人很多。明白了
run:
How many total P values?
9
How many total N values?
5
Overall Information gain = 0.9402859586706309
How many distinct values of an attribute?
3
Enter pi for all attributes
2
4
3
Enter ni for all attributes
3
0
2
Attribute   pi  ni  I(pi,ni)
attrib1     2.0     3.0     0.9709505944546686
attrib2     4.0     0.0     NaN
attrib3     3.0     2.0     0.9709505944546686
BUILD SUCCESSFUL (total time: 17 seconds)