#define RADIX 1000000000
#define PI 3.1415926535897932384626433832795
#define E 2.7182818284590452353602874713527
#ifndef DWORD
typedef unsigned long DWORD;
#endif
DWORD rad=RADIX;
int calcResultLen(DWORD n) //use stirling to calc the length of n!
{
if (n<=1)
return 1;
return log10(2*PI*(double)n)/2 + n * log10((double)n/E)+1;
}
DWORD calcCore(DWORD *p,DWORD n,DWORD c)
{
_asm
{
push ebx
;
mov ebx,p
xor edx,edx
mov eax,[ebx]
mul n
add eax,c
adc edx,0
div rad
mov [ebx],edx
;
pop ebx
}
}
void Num2Str(DWORD n, char *strEnd)
// number convert to string, in order to improve speed
// don't use lib function sprintf
{
char *p;
int i;
for ( i=0,p=strEnd;i<9;i++)
{
*p-- =( n % 10 +'0');
n /=10;
}
}
DWORD* calc( DWORD n, DWORD *pBuff,int buffLen)
{
DWORD *p; //lowest unit
DWORD *pEnd=pBuff+buffLen-1; //highest unit
DWORD c; //c carry number
//---------------
*pEnd=1;
while (n>1)
{
for (c=0,p=pBuff+buffLen-1;p>=pEnd;p--)
c=calcCore(p,n,c);
time=GetTickCount();
for (p=pEnd,pChar=pRes+8;p<pBuff+buffLen;p++)
{
Num2Str(*p,pChar);
pChar+=9;
}
pChar=pRes;
while ( *pChar=='0' ) pChar++; //skip the pre zero
fwrite(pChar,1,pRes+buffLen*9-pChar,fp); // write whole of result