A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 权跃杰 中级黑马   /  2012-7-31 16:20  /  2344 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

老师或高手请进!!
对比下列2段代码:
代码1
class A{
  public static void main(String args[]){
     System.out.println("1!+2!+3!+4!+...+18!+19!+20!="+sum()) ;
  }
  public static long sum(){   //求出所有数字阶乘的和
     long sum = 0l ;
     for(int i = 1 ; i <= 20 ; i++){
        sum+=num(i) ;
     }
     return sum ;
  }
  public static double num(int x) {  //求出单个数字的阶乘是多少
    if(x==0||x==1){
       return 1 ;
    }else{
       return x * num(x-1) ;
    }
  }
}



代码2
public class Practice11{
public static void main(String args[]){
  long sum = 0L;
  for (int x = 1; x<=20; x++){
   sum += Factorial(x);
  }
  System.out.println("1!+2!+3!+...+20!结果是:" + sum);
}
public static long Factorial(int k){
  if (k == 0||k == 1){
   return 1;
  }else{
   return k * Factorial(k-1);
  }
}
}


为什么产生的结果不一样!
第一个结果是:1!+2!+3!+4!+...+18!+19!+20!=2561327494111820288
第二个结果是:1!+2!+3!+...+20!          结果是:2561327494111820313

不是我这人较劲啊,为什么结果不同?请老师或者高手给予解答?

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1 赞一个!

查看全部评分

7 个回复

倒序浏览
public class Test2{
public static void main(String args[]){
  long sum = 0L;
  for (int x = 1; x<20; x++){//这里改为x<20就OK了,循环次数问题哈
   sum += Factorial(x);
  }
  System.out.println("1!+2!+3!+...+20!结果是:" + sum);
}
public static long Factorial(int k){
  if (k == 0||k == 1){
   return 1;
  }else{
   return k * Factorial(k-1);
  }
}
}
回复 使用道具 举报
sorry 错了 我运行错了哈 没看清哈
回复 使用道具 举报
问题出在代码1上,以下是你的代码

class A{
  public static void main(String args[]){
     System.out.println("1!+2!+3!+4!+...+18!+19!+20!="+sum()) ;
  }
  public static long sum(){   //求出所有数字阶乘的和
     long sum = 0l ;
     for(int i = 1 ; i <= 20 ; i++){
        sum+=num(i) ;
     }
     return sum ;
  }
  public static double num(int x) {  //这里的返回值类型是double,而你运算的结果应该是long,在这里,丢失精度了,你把double改回long就可以啦,是精度损失的问题
    if(x==0||x==1){
       return 1 ;
    }else{
       return x * num(x-1) ;
    }
  }
}
回复 使用道具 举报
传入19的时候两个结果一样  传入21的时候会出现负数  所以可以说明了计算的结果超过了long类型的存储范围了
回复 使用道具 举报
第2段代码是对的,第1段代码中问题应该在 public static double num(int x) 中,整个运算都是整形运算,
为什么要加入DOUBLE浮点运算呢?  你把DOUBLE 该成LONG就没有问题了。
另外,运算方面有点问题,虽然不影响最后的结果,
但我还是想说,你仔细观察第一段代码中的X  和  第二段代码中的K  其实他们的值永远也到不了“0”,
你看看对不对,比如现在执行到return k * Factorial(k-1);语句,假设此时K=2,  执行K-1后新的K=1,
调用Factorial(K)函数,就进入IF判断环节,当判断为1后,返回值,IF语句就完全退出了,不再循环了。
也就不存在再次调用Factorial(K)函数,所以IF语句中对K=0的判断是多余的,去掉后运行结果没有改变。
最后,很感谢让我学到了一种新的循环方式!祝进步

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1 赞一个!

查看全部评分

回复 使用道具 举报
刚想回,发现没权限,弄好了回来发现被LS回答了。。。。
第一段代码的num()函数返回值类型不对,应为long
补充一点说,5!以上都是个位数为0的数,所以你很容易只算出1-4的阶乘的个位数,就能很容易判断出是,第二段代码的返回值相对准确。

评分

参与人数 1黑马币 +10 收起 理由
杨志 + 10 鼓励一下!

查看全部评分

回复 使用道具 举报
问题已解决
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马