今天無心中看到一篇博客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