??? 假如我們要精確計算一個很大的數,比如說,256的階乘(結果有500多位),怎么辦?
你會說,很好辦啊,從JDK 1.1起Java不是提供了一個java.math.BigInteger嗎?不錯,用BigInteger確實能解決問題。不過,如果沒有Sun給的這個class,僅僅靠Java最基本的那些類型,我們有沒有辦法來進行計算呢?答案是,肯定是能嘛,要不然在BigInteger之前怎么辦。
方法之一就是用數組來表示。比如說:
??????????????????????? int[] data = new int[100];
??? 我們知道,一個int的最大值為2^31-1即2147483647(10位),如果我們把這100個int值串起來,我們就能表示一個1000位的數。這里我們就用這種方式來計算256的階乘(256!)。
??? 我們先分配100個int的數組,由于是static,所以每個int的初始值都是0。
??? 然后每個int表示6位數,即最大值為999999。因為我們要做乘法,如果給int的位數過大,如9位,那么999999999乘上一個數,如100,它的值就大于了int的max值,造成溢出。所以int表示的位數需要根據需要仔細選擇。(用long來表示也同樣需要仔細權衡位數)
??? 再定義一個num來表示我們占用的數組的int個數
??? 在乘法的時候,對每個占用的int中的數都要乘,然后一個一個地判斷每個int中的值是不是超出了6位:
??????????????????????? if (data[j]) > 1000000)
??? 如果超出了則需要進位:
??????????????????????? data[k+1] += data[k]/1000000;
??????????????????????? data[k] %= 1000000;
一個個判斷,最后,如果最高位(即data[num])中的數值也超過了6位,我們就需要占用一個新的int,同樣地進位,當然也不要忘了給num加一。
??????????????????????? if (data[num] > 1000000) num++;
??? 最后,將我們的數組順序輸出即可。在輸出的時候需要小心的是,如果int中的值小于6位,如25,別忘了補上0,即000025,否則你會得到錯誤的答案的。
??? 完整的代碼如下:
package?tmp;
/**
?*
?*?@author?Stevech
?*/
public?class?BigNumbers?{
????static?int[]?data?=?new?int[100];
????
????/**?Creates?a?new?instance?of?BigNumers?*/
????public?static?void?main(String[]?args)?{
????????int?num?=?0;????//?占用的個數
????????data[0]?=?1;????//?0和1的階乘是1
????????
????????for?(int?i?=?2;?i?<?257;?i++)?{
????????????for?(int?j?=?0;?j?<?num?+?1;?j++)?{
????????????????data[j]?*=?i;????????//?對每個int中的數都乘上?i
????????????}
????????????for?(int?j?=?0;?j?<?num?+?1;?j++)?{
????????????????if?(data[j]?>?1000000)?{
????????????????????for?(int?k?=?j;?k?<?num?+?1;?k++)?{
????????????????????????if?(data[num]?>?1000000)?num++;
????????????????????????data[k+1]?+=?data[k]/1000000;????//?進位
????????????????????????data[k]?%=?1000000;??????????????????//?進位后的余數
????????????????????}
????????????????}
????????????}
????????}
????????System.out.println("占用的int數:"?+?(num+1)?+?"\n值:");
????????System.out.print(data[num]);
????????for?(int?i?=?num-1;?i?>?-1;?i--)?{
????????????System.out.print(new?java.text.DecimalFormat("000000").format(data[i]));
????????}
????}
}
輸出結果為:
占用的int數:85
值:
85781777534284265411908227168123262515778152027948561985965565037726945255314
75893774402913604514084503758853423365843061571968346936964753222892884974260256
79637332563368786442675207626794560187968867971521143307702077526646451464709187
32610083287632570281898077367178145417025052301860849531906813825748107025281755
94594769870346657127381392862052347568082188607012036110831520935019474371091017
26968262861606263662435022840944191408424615936000000000000000000000000000000000
000000000000000000000000000000