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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7461803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 20:04:16  来源:igfitidea点击:

Why Quadratic equation's root result is NaN ? (Java)

javamath

提问by blaces

Why write out The roots are NaN and NaNin console? I've read about NaN, but I don't find the right solution how can I repair the mistakes... I've tried casting to doublethe discriminantand the rootsbut doesn't work. Can somebody help me, where and what I need to rewrite?

为什么在控制台中写出 根是 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);
    }

回答by hammar

Math.sqrt(x)returns NaNwhen xis negative, which then propagates through the rest of your code. You'll want to test for negative numbers beforetaking the square root:

Math.sqrt(x)NaNx为负时返回,然后通过其余代码传播。取平方根之前,您需要测试负数:

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

回答by Jon Skeet

Firstly, let's get rid of user input as a cause for this - it's much easier if the short but complete program contains all the data we need:

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

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

This shows two cases - one where there really areroots - but the program claims there aren't - and one where there really aren'treal roots, but the program prints them out as NaN. When you take the square root of a negative number, the result is NaN, which is why that's being displayed.

这显示了两种情况 - 一种情况下确实根 - 但程序声称没有 - 一种情况下确实没有真正的根,但程序将它们打印为 NaN。当你取负数的平方根时,结果是 NaN,这就是显示它的原因。

So, the problem is how you're dealing with the discriminant. There are real roots if b2- 4acis non-negative - but you've already taken the square root at that point andreversed the nature of the condition.

所以,问题是你如何处理判别式。如果b 2- 4ac为非负数,则有实数根- 但您此时已取平方根反转条件的性质。

So, it should be:

所以,应该是:

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

Lessons to learn:

学习经验:

  • When you want to demonstrate a problem, it helps to keep it minimal; using hard-coded values is a good way of doing this
  • Be careful about the order of operations - in this case, you were trying to judge something using the wrong value because you'd taken the square root too early
  • Be careful with conditions and whether or not you're getting them the right way round
  • 当你想演示一个问题时,它有助于保持最小;使用硬编码值是这样做的好方法
  • 注意操作顺序 - 在这种情况下,您试图使用错误的值来判断某些东西,因为您过早地取平方根
  • 小心处理条件以及您是否以正确的方式处理它们

EDIT: As noted in comments, there are various special cases to consider too, including when ais 0 which would otherwise lead to a division by 0 issue.

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

回答by Shivan Dragon

You get that when your discriminant is negative. Like for a=1,b=2,c=3. Delta = 2*2 -4*1*3 = 4 - 12 = -8

当您的判别式为负时,您会得到它。就像 a=1,b=2,c=3。增量 = 2*2 -4*1*3 = 4 - 12 = -8

Java can't calculate square root of negative number, it doesn't know about imaginary number i.

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

回答by Jiri Kriz

Do

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