入門篇之二
在《大數階乘之計算從入門到精通―入門篇之一》中,我們給出乙個計算階乘的程式,它採用char型陣列存貯大數,1個元素表示1位十進位制數字,在計算時,一次乘法可計算一位數字和乙個整數的乘積。該演算法具有簡單直觀的優點,但缺點也是明顯的,速度不快,占用記憶體空間也較多,本文將給出乙個改後的程式,有效的克服了這些缺點。
學過80x86彙編的人都知道,8086/8088的cpu可對兩個16位元的數相乘,其結果為32位元,80386及其後的32位cpu可對兩個32位元的數相乘,結果為64位元(以下寫作bit)。8086 cpu等16位cpu已完全淘汰,這是不去討論它。在32位c語言編譯器中,unsigned long(dword)型變數可以表示乙個32bit的整數,unsigned short(word)型變數可表示乙個16bit的整數。兩個65535以內的數相乘,其結果完全可以存貯在乙個unsigned long變數中。另外,在好多32位編譯器中,也提供了64bit的整數型別(如在vc中,unsigned __int64可表示乙個64bit的整數,在gcc中,long long可表示乙個64位的整數)。同理兩個40億以內的數相乘,其結果可以用乙個unsigned __int64 型的變數來儲存。讓乙個具有一次可計算兩個32bit數乘法能力的cpu一次只計算1個1位10進製數和乙個整數的乘法,實在是一種浪費。下面我們提出兩種大數的表示法和運算方法。
第一種方法:用word型陣列表示大數,用dword型變數表示兩個word型變數的乘積。陣列的每個元素表示4位十進位制數。在運算時,從這個數的最後乙個元素開始,依次乘以當前乘數並加上上次的進製,其和的低4位數依然存在原位置,高幾位向前進製。當乘數i小於42萬時,其乘積加上進製可以用乙個dword型變數表示,故這個程式可以計算上到42萬的階乘,當計算42萬的階乘時,占用記憶體空間小於1.1兆位元組。至於速度,在計算1000/10000的階乘時,在迅馳1.7g電腦約需0.015/0.86秒。
#include "stdlib.h"
#include "stdio.h"
#include "math.h"
#define pi 3.1415926535897932384626433832795
#define rad 10000
typedef unsigned long dword;
typedef unsigned short word;
//用stirling公式估算結果長度,稍微算得大一點
dword calcresultlen(dword n,dword rad)
void calcfac1(dword n)
//---計算並分配所需的儲存空間
len=calcresultlen(n,rad);
buff=(word*)malloc( sizeof(word)*len);
if (buff==null)
return ;
//以下**計算n!
phead=ptail=buff+len-1;
for (*ptail=1,i=2;i<=n;i++)
while (carry>0)
}//顯示計算結果
printf("%d!=%d",n,*phead);
for (p=phead+1;p<=ptail;p++)
printf("%04d",*p);
printf("/n");
free(buff);//釋放分配的記憶體
}int main(int argc, char* argv)
#define ten9 1000000000
void calcfac2(dword n)
//---計算並分配所需的儲存空間
t=gettickcount();
len=calcresultlen(n,ten9);
buff=(dword*)malloc( sizeof(dword)*len);
if (buff==null)
return ;
//以下**計算n!
phead=ptail=buff+len-1;
for (*ptail=1,i=2;i<=n;i++)
while (carry>0)
}t=gettickcount()-t;
//顯示計算結果
printf("it take %d ms/n",t);
printf("%d!=%d",n,*phead);
for (p=phead+1;p<=ptail;p++)
printf("%09d",*p);
printf("/n");
free(buff);//釋放分配的記憶體
}
大數運算 7 大數階乘 求階乘
對於大數來說,乙個數的階乘是非常大的,同樣,乙個int型別的整數,他的階乘就有可能會很大。就拿50來說,他的階乘位數是65位,就已經遠遠超過了long long int型別的最大值。這時候,我們要通過字串的方法,來進行階乘的運算。當然,需要注意的是 我們所求乙個數的階乘,這個數是在int範圍內的,5...
演算法題目1 大數的階乘
這個問題是乙個朋友聊天的時候突然聊到,在計算c語言中如何計算大數的階乘。10!在c語言完全沒問題,但是如果是100!1000!的話如何實現。當時我不加思索給出下的 大數的階乘 100!錯誤 define crt secure no warnings include include include i...
NYOJ 28 大數階乘
題意 對於比較小的n,求其階乘的時候可以用遞迴解決。但是如果n很大的時候,比如1000,那麼n 肯定超出整形資料所能表示的範圍。因此必須採用其它方法解決,通常解決大數運算資料超出範圍的問題時採用陣列去模擬。其實求算n 可以看成是每次兩個整數相乘的過程,因此可以模擬成大數相乘的過程。只是需要增加一些變...