为什么二次方程的根结果是NaN? (JAVA)

时间:2011-09-18 13:35:06

标签: java math

为什么写出来 控制台中的根是NaN和NaN ? 我读过关于NaN的文章,但是我找不到合适的解决方案如何修复错误...... 我已经尝试强制转换 判别但是不起作用。 有人可以帮助我,我需要重写的地方和内容吗?

public static void main(String args[]) {
    Scanner sc = new Scanner(System.in);
    Pattern newlineOrSpace = Pattern.compile(System
            .getProperty("line.separator")
            + "|\\s");
    sc.useDelimiter(newlineOrSpace);
    System.out.print("Enter a, b, c: ");
    double a = sc.nextDouble();
    double b = sc.nextDouble();
    double c = sc.nextDouble();
    // System.out.format("a = %f, b = %f, c = %f", a, b, c);

    double root1;
    double root2;
    double discriminant;
    discriminant = Math.sqrt(b * b - 4 * a * c);
    if (discriminant > 0) {
        System.out.println("There are no real roots ");
    } else {
        root1 = (-b + discriminant) / (2 * a);
        root2 = (-b - discriminant) / (2 * a);
        System.out.println("The roots are " + root1 + " and " + root2);
    }

4 个答案:

答案 0 :(得分:7)

Math.sqrt(x)为否定时,

NaN会返回x,然后传播通过其余代码。你需要在取平方根之前测试负数

discriminant = b * b - 4 * a * c;
if (discriminant < 0) {
    System.out.println("There are no real roots ");
} else {
    root1 = (-b + Math.sqrt(discriminant)) / (2 * a);
    root2 = (-b - Math.sqrt(discriminant)) / (2 * a);
    System.out.println("The roots are " + root1 + " and " + root2);
}

答案 1 :(得分:5)

首先,让我们摆脱用户输入作为原因 - 如果简短但完整的程序包含我们需要的所有数据,那就容易多了:

public class Test {
    public static void main(String args[]) {
        showRoots(2.0, 10.0, 2.0);
        showRoots(10.0, 1.0, 1.0);
    }

    private static void showRoots(double a, double b, double c) {
        double discriminant = Math.sqrt(b * b - 4 * a * c);
        if (discriminant > 0) {
            System.out.println("There are no real roots ");
        } else {
            double root1 = (-b + discriminant) / (2 * a);
            double root2 = (-b - discriminant) / (2 * a);
            System.out.println("The roots are " + root1 + " and " + root2);
        }
    }
}

这显示了两个案例 - 其中一个确实 根 - 但程序声称没有 - 而且其中一个不是真正的根,但是程序将它们打印为NaN。当你取负数的平方根时,结果是NaN,这就是显示它的原因。

所以,问题在于你是如何处理判别式的。如果 b 2 - 4ac 是非负的,那么确实存在根源 - 但是你已经在那个时间点采用了平方根并且颠倒了条件的性质。

所以,它应该是:

private static void showRoots(double a, double b, double c) {
    double discriminant = b * b - 4 * a * c;
    if (discriminant < 0) {
        System.out.println("There are no real roots ");
    } else {
        double discriminantRoot = Math.sqrt(discriminant);
        double root1 = (-b + discriminantRoot) / (2 * a);
        double root2 = (-b - discriminantRoot) / (2 * a);
        System.out.println("The roots are " + root1 + " and " + root2);
    }
}

要学习的经验教训:

  • 当你想要证明一个问题时,它有助于保持最小化;使用硬编码值是一种很好的方法
  • 注意操作的顺序 - 在这种情况下,你试图使用错误的值来判断某些东西,因为你过早地采用了平方根
  • 小心条件,不管你是否正确地使用它们

编辑:正如评论中所述,还有一些特殊情况需要考虑,包括a为0时否则会导致除以0问题。

答案 2 :(得分:1)

待办事项

double discriminant = b * b - 4 * a * c; 
if (discriminant >= 0) {
    discriminant = Math.sqrt(discriminant);  
    root1 = (-b + discriminant) / (2 * a);          
    root2 = (-b - discriminant) / (2 * a);          
    System.out.println("The roots are " + root1 + " and " + root2);      
} 
else {
    System.out.println("There are no real roots ");  
} 

答案 3 :(得分:1)

当你的判别力为负时你就明白了。像a = 1,b = 2,c = 3。 Δ= 2 * 2-4 * 1 * 3 = 4-12 = -8

Java无法计算负数的平方根,它不知道虚数i。