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.
精彩评论