今天无心中看到一篇博客http://www.oschina.net/code/snippet_253900_27679,做者在里面提到一个问题是经过java处理100!的结果的各位数之和为多少? javascript
由于Java有着严格的数据类型机制,数据会越界.看到问题个人思路其实也很简单,就是把100的阶乘这个数拿到,而后拆成一位数一位数的数组,把全部数字加成合计就行了.写完发现for循环便利一个这么大的数字简直是灾难,在浏览器的控制台中看这个数字100!显示为:9.33262154439441e+157 java
这种指数表示的方式,表明数字的大小是9.33262154439441 * (10的157次方).这里的问题是要求这个数的各位数之和,因此0是没有运算的必要的,那么9.33262154439441e+157中e以前的数字之和才是咱们须要的,这么一来就简单了. 数组
代码以下: 浏览器
<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,表示无穷大.若是对这个问题继续有兴趣,能够看看大数阶乘. spa
这个计算通过网友指出确实是存在错误的,由于精度丢失的缘由,指数表达不彻底100!的大小.这个寻找了一下网上关于javascript进行这种大数运算的例子确实比较少,由于在通常观点里javascript就是操做页面特效的简单语言,对于计算不怎么擅长. .net
后来在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设计初衷就没有为这类大数计算留有太多余地. code