开发者

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

开发者 https://www.devze.com 2023-04-05 11:51 出处:网络
Why write out The roots are NaN and NaN in console? I\'ve read about NaN, but I don\'t find the right solution how can I repair the mistakes...

Why write out The roots are NaN and NaN in 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 double the discriminant and the roots but doesn't work. Can somebody help me, where and what I need to rewrite?

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


Math.sqrt(x) returns NaN when x is negative, which then propagates through the rest of your code. You'll want to test for negative numbers before taking the square root:

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


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 are roots - but the program claims there aren't - and one where there really aren't real 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.

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

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 a is 0 which would otherwise lead to a division by 0 issue.


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


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

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

0

精彩评论

暂无评论...
验证码 换一张
取 消