黑马程序员技术交流社区

标题: 求阶层分之一 [打印本页]

作者: 罗磊    时间: 2012-6-30 16:17
标题: 求阶层分之一
需求:求阶层分之一的和!小弟这么想!
public static void add()
{
  double num=1.0;
  int x =1;
  int y=1;
  while(x<=20)
  {
   for(int i=1;i<=x;i++)
   {
    y*=i;
   }
   num +=1/y;//这里怎么报了除0错误!求大师指点!
   x++;
  }
  System.out.println(num);
}
作者: 王莹    时间: 2012-6-30 16:47
本帖最后由 王莹 于 2012-6-30 16:49 编辑

代码说明问题:

class Number{
public static void main(String[] args) throws Exception
    {
      double num=1.0;
      int x =1;
      int y=1;
      while(x<=20)
  {
     for(int i=1;i<=x;i++)
   {
     y*=i;
      }
     System.out.println(x+"  y  : "+y);    //打印y的值
     System.out.println("num____1: "+num);   //运算之前打印
     num +=1/y;//这里怎么报了除0错误!求大师指点!
     System.out.println("num____2: "+num); //运算之后打印
     x++;
  }
  System.out.println(num);
}
}

在你的程序里添加了两条验证性的语句,帮助找出错误。



从图中可以看出运行到x=10时,由于10!的阶层运算过小,在计算机中已经以0来计算,故而会报错。

以后发现有什么运行结果弄不清楚的时候,可以适当添加一些这些打印的语句,帮助了解问题所在之处。

希望可以帮到你~~


result_1.png (4.97 KB, 下载次数: 37)

result_1.png

作者: wht    时间: 2012-6-30 17:14
可能是y的值太小了,应经近似于0
作者: wht    时间: 2012-6-30 17:14
是1/y,不好意思写错了
作者: 贾飞雨    时间: 2012-6-30 17:29
本帖最后由 yufeiant 于 2012-6-30 17:30 编辑

在你的程序编写中,你 的num的输出语句是在while循环之外的,在循环中num的值是如何被改变的在你运行程序的时候你是看不出来,所以光读程序更本就读不出来,
在你的程序中加了一句话

class Demo
{
public static void main(String [] args)
{
        add();
}
public static void add()
        {
  double num=1.0;
  int x =1;
  int y=1;
  while(x<=20)
  {
   for(int i=1;i<=x;i++)
   {
    y*=i;
   }
   System.out.println(x+"+"+y);//这里给你加了一句话,看了一下在while循环之前y的值是如何变化的,
   num +=1/y;//这里怎么报了除0错误!求大师指点!
   x++;
  }
  System.out.println(num);
        
        }
}
下面是运算的结果

1+1
2+2
3+12
4+288
5+34560
6+24883200
7+857276416
8+-511705088
9+1073741824//我们可以在这里看到,在for循环x是9的时候,y的值已经高达1073741824,当x等于10的时候,y的数值是那个数的平方,远远超出了int的取值范围,所以就变为了0
10+0
Exception in thread "main" java.lang.ArithmeticException: / by zero
        at Demo.add(Demo.java:24)
        at Demo.main(Demo.java:7)
请按任意键继续. . .

下面哥们给你用2禁制来玩一下   这次就好理解了
int型取值最大是这个吧2^31-1,如果打2^31的数值是这个214748368,转换成二进制就是这个样子了
1 0000 0000 0000 0000 0000 0000 0000 0000超出了32位,前面加了一个1,但是int只取32位,所以就是0了,
那刚才那个数远远的大于了int的取值,所以就变为了0,所以就报错了






file:///C:\Users\Administrator\AppData\Roaming\Tencent\Users\493322470\QQ\WinTemp\RichOle\BC`BV%RHN1~ZX8F6T{$Q5IF.jpg

file:///C:\Users\Administrator\AppData\Roaming\Tencent\Users\493322470\QQ\WinTemp\RichOle\BC`BV%RHN1~ZX8F6T{$Q5IF.jpg





作者: 谭立文    时间: 2012-6-30 17:36
在这里给你提供了两种解决方案 第一种 :
public static void add()
{
          double num=1.0;
          int x =1;
          
          while(x<=20)
          {
                  long  y = 1;    //将  int y = 1; 定义为long型并放置在while循环里面
              //比如说你求完 4的阶乘后    y = 1 * 2 * 3 * 4 = 24;按照你的思路重新利用循环
              //来求5的阶乘  y * = i  如果y不重新置为1  那么求5的阶乘相当于求的是5 ! * 4 !
              //20! = 2432902008176640000 如果你每次求完一个数后都没有重新将y置为1
              //即时是long也不够用 所以会超出范围 而超过范围后系统会抛出异常并返回一个零值(这个是我自己用代码分析推断的
                  //所以1 / y 会提示除零错误
              for(int i=1;i<=x;i++)
              {
                      y*=i;
              }
              num +=1/y;//这里怎么报了除0错误!求大师指点!
              x++;
              System.out.println(y);
          }
          System.out.println(num);
        }
其实这个代码的效率不是最高的,因为你求完5的阶乘求6的阶乘不需再重新重新1 * 2 * 3 * 4 * 5 * 6  只需要5的阶乘 * 6因为5的阶乘已经求过,根据这个思路我在最小限度改你代码并帮你完善了,希望对你有帮助。

public static void add()
        {
                double num = 1.0;
                int x = 1;
                long y = 1;
                while (x <= 20)
                {
                        y *= x;
                        num += 1 / y;// 这里怎么报了除0错误!求大师指点!
                        x++;
                        System.out.println(y);
                }
                System.out.println(num);
        }
作者: 罗磊    时间: 2012-6-30 22:22
哦哦!原来如此啊!谢谢各位大虾啊!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2