2013-03-02 185 views
0

在我的代碼中,我只是試圖做一個簡單的程序,告訴你如果一個數字可以平均分成另一個數字(在這種情況下,該數字是3)。現在我要說的是,如果x(數字不能均等地加上0.01,那會給我堆棧溢出錯誤,如果我把它的值設爲0.2,那麼說9是可以除以3的整數。 。進入三三後6遞歸方法堆棧溢出錯誤

public class divisible { 

    public static void divide(double x) { 
     double three = 3; 
     double value = x%three; 

     if (value==0) { 
     System.out.println(x + " is a divisible of 3 "); 
     return; 
     }else{ 
     //System.out.println("x does not divide evenly into 3"); 
     divide(x+(.01)); 
     } 

    } 

    public static void main(String args[]) { 
     divide(4); 
    } 
} 
+0

System.out.println(x);你可以在你的其他聲明中試試這個嗎?它可以幫助你確定x是什麼,看看它是否變成了6. – 2013-03-02 07:17:25

+0

有一個名爲'three'的變量和給它賦值'3'是非常多餘的。你應該有一個有意義的名字,並把它變成一個類變量。 – Maroun 2013-03-02 07:27:27

回答

1

你的問題是,你比較兩個雙打==這將產生不可靠的結果,原因在於浮點運算的實現方式你的方法應該是這樣的:

public static void divide(int x) { 
    int three = 3; 
    int value = x%three; 

    if (value==0) { 
    System.out.println(x + " is a divisible of 3 "); 
    return; 
    }else{ 
    System.out.println("x does not divide evenly into 3"); 
//   divide(x+(.01)); 
    } 

} 

如果您想要使用雙參數訪問該方法,您可以投射:

public static void divide(double x) { 
    x = (int) Math.round(x); 

如果你希望能夠處理比Integer.MAX_VALUE數量較多,可以使用BigInteger

3

究其原因,遞歸是無限有點晦澀:在0.1不能精確地double表示。當您將0.1添加到3十次時,您會做而不是獲得4 - 您會得到一個與4接近的數字,但比它大一點。這個數字並沒有平均分配你的目標,所以遞歸進行到4.14.2等等,沒有結束。

的道理是一樣的,爲什麼這個循環永遠不會停止(try it!):

for (double x = 3 ; x != 4 ; x += 0.1) { 
    System.out.println(x); 
} 

使用BigDecimal代替double將解決這個問題,因爲0.1會準確表示。當然,它仍然會打印錯誤的消息("is divisible of 3"是硬編碼的,即使x在餘數爲零時可能是一個完全不同的數字)。