递归方法Stack Overflow错误

时间:2013-03-02 07:11:30

标签: java recursion stack-overflow

在我的代码中,我只是想制作一个简单的程序,告诉你一个数字是否可以均匀地分成另一个数字(在这种情况下,这个数字是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);
   }
}

2 个答案:

答案 0 :(得分: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可能是完全不同的数字。)

答案 1 :(得分: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));
  }

}

如果希望使用double参数访问该方法,则可以强制转换:

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

如果您希望能够处理大于Integer.MAX_VALUE的数字,可以使用BigInteger