简体   繁体   English

递归方法堆栈溢出错误

[英]recursion method Stack Overflow error

In my code i am just trying to make a simple program that tells you if one number can divide into another number evenly (in this case that number is 3). 在我的代码中,我只是试图编写一个简单的程序,告诉您一个数字是否可以平均划分为另一个数字(在这种情况下,该数字为3)。 right now I am saying that if x (the number doesnt divide evenly add 0.01 to it, that gives me the stack overflow error. If I make the value 0.2 it says that 9 is a divisible of three when really the next thing number that divides into three after three is 6 现在我说的是,如果x(数字未平均除以0.01),则会给我带来堆栈溢出错误。如果我将值设置为0.2,则表示9实际上是下一个要除的事物数除以3的结果成三成三就是六

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

The reason the recursion is infinite is a little obscure: the 0.1 cannot be represented exactly in double . 递归无限的原因有点模糊: 0.1不能精确地表示为double When you add 0.1 to 3 ten times, you do not get a 4 - you get a number that's close to 4 , but a little greater than it. 当您将0.1乘以3十次时,您得到的不是 4您得到的数字接近4 ,但比它大一点。 That number does not divide your target evenly, so the recursion goes on to 4.1 , 4.2 , and so on, with no end. 这个数字不将你的目标均匀,所以递归那张4.14.2 ,依此类推,满意没有终点。

The reason is the same why this loop never stops ( try it! ): 原因相同,因此此循环永不停止( 尝试一下! ):

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

Using BigDecimal in place of double would fix the problem, because 0.1 would be represented exactly. 使用BigDecimal代替double可以解决此问题,因为将精确表示0.1 Of course it would still print a wrong message (the "is divisible of 3" is hard-coded, even though x could be an entirely different number in the invocation when the remainder becomes zero). 当然,它仍然会打印一条错误消息( "is divisible of 3"是硬编码的,即使x在其余部分变为零时在调用中可能是一个完全不同的数字)。

Your problem is that you compare two doubles with == . 您的问题是您将两个双打与==进行比较。 This will produce unreliable results, due to the way that floating point arithmetic is implemented. 由于执行浮点运算的方式,这将产生不可靠的结果。 Your method should look like this: 您的方法应如下所示:

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

}

If you want the method to be accessed with a double argument, you can cast: 如果要使用双参数访问该方法,则可以强制转换为:

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

If you want to be able to handle number larger than Integer.MAX_VALUE , you can use BigInteger 如果您希望能够处理大于Integer.MAX_VALUE ,则可以使用BigInteger

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM