2011-09-18 66 views
2

为什么要写出 在控制台中的根是NaN和NaN? 我读过有关NaN的,但我没有找到合适的解决方案,我怎么能修复的错误...... 我已经试过铸造翻番判别但不工作。 有人可以帮助我,我需要重写什么?为什么二次方程的根结果是NaN? (Java)

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

我会肢体出去,猜测'a'很小,甚至可能为零。你想在这种情况下做什么功能? – Beta

+0

你给什么输入? – geoffspear

+1

由于Hammar推断,但没有明确说明,判别式D由D = b^2 - 4ac给出。 Upi ...更多信息在http://en.wikipedia.org/wiki/Discriminant – andand

回答

7

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

我建议检查条件像a = 0;一个根是零,另一个是-c/b。容易做到,而且都是真实的。还有更多的退化病例要查找,而不仅仅是零行列式。 – duffymo

+0

我可以只建议使用Math.abs()作为负数吗?例如,我想计算一个距离,并不在乎数字是否定的或积极的。 – Joehot200

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

+0

我建议检查条件像a = 0;一个根是零,另一个是-c/b。容易做到,而且都是真实的。还有更多的退化病例要查找,而不仅仅是零行列式。 – duffymo

+0

@duffymo:补充说明,谢谢。 –

1

当您的判别式为负时,您会得到这个结果。就像a = 1,b = 2,c = 3一样。 Delta = 2 * 2 -4 * 1 * 3 = 4 - 12 = -8

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