javascript解决

我只是一个虾纸丫 提交于 2019-11-28 17:05:20

    今天无意中看到一篇博客http://www.oschina.net/code/snippet_253900_27679,作者在里面提到一个问题是通过java处理100!的结果的各位数之和为多少?

    因为Java有着严格的数据类型机制,数据会越界.看到问题我的思路其实也很简单,就是把100的阶乘这个数拿到,然后拆成一位数一位数的数组,把所有数字加成合计就好了.写完发现for循环便利一个这么大的数字简直是灾难,在浏览器的控制台中看这个数字100!显示为:9.33262154439441e+157 

    这种指数表示的方式,代表数字的大小是9.33262154439441 * (10的157次方).这里的问题是要求这个数的各位数之和,所以0是没有运算的必要的,那么9.33262154439441e+157e之前的数字之和才是我们需要的,这么一来就简单了.

    代码如下:

<script>
  function jc(x){
    var jg = 0;
    if(x === 1){
      return 1;
    }else{
      jg = x * jc(x-1);
    }
    return jg;
  }
  
  var result = jc(100).toExponential().toString();
  result = result.replace(".","");
  var r = result.substr(0,result.indexOf("e"));
  var arr = r.split("");
  var jg = 0;
  for(var i=0;i<arr.length;i++){
    jg = jg + Number(arr[i]);
  }
  console.log(jg);
</script>

    结果是60,运算速度很快,因为没有大数字的for循环.这是100!的结果,如果运算到171时,就会超出javascript中存储的极限,那个数字显示为 Infinity,表示无穷大.如果对这个问题继续有兴趣,可以看看大数阶乘.

    这个计算经过网友指出确实是存在错误的,因为精度丢失的原因,指数表达不完全100!的大小.这个寻找了一下网上关于javascript进行这种大数运算的例子确实比较少,因为在一般观点里javascript就是操作页面特效的简单语言,对于计算不怎么擅长.

    后来在51js上找到一段关于大数阶乘运算的代码,它将结果通过字符串的形式表现.

function factorial(n) {
  var a = [1];
  for (var i = 1;i<=n ;i++) {
    for (var j = 0, c = 0;j<a.length || c != 0;j++ ) {
      var m = (j < a.length) ? (i*a[j] + c) : c;
      a[j] = m % 10;
      c = (m - a[j]) / 10;
    }
  }
  return a.reverse().join("");
}
    然后再通过之前的方式计算各位数的合计,计算结果是648.这个结果和本文开篇提到的那篇博客的结果不一样的,经过我的手工验证,应该那篇博客里23!开始就计算有错误.

    这类问题的核心思想不在于单纯的计算,而是对于大数的保存,确保精度不丢失,以及分治的思想.具体有兴趣可以百度大数阶乘,因为javascript设计初衷就没有为这类大数计算留有太多余地.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!