2011-09-18 64 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。