2013-03-02 187 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在余数为零时可能是一个完全不同的数字)。