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

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

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

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

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

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

要吸取的教训:

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

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

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

当你的判别力为负时,你就会得到这个。 像a = 1,b = 2,c = 3。 Δ= 2 * 2-4 * 1 * 3 = 4-12 = -8

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