这句啥意思,判断长度吗len=(int)log10(s)+1
1000的阶乘十进制数有2568位,double不行。末尾的0有249位,除去它还有2319位。
这题可以简单地直接算出n的阶乘再求其最高位,不过这样就普通了。
另一个方法是只保留前几位来计算。难点在于如何证明保留多少位就够算了。实际中1000的阶乘保留6位就足矣保证最高位的精度了。
#include <stdio.h> #include <math.h> // 方法1 // sterling公式 = | 10^( log(n!) - |log(n!)| ) | unsigned sterling( unsigned n ) // n<=1000 { double a = 0.0; for( unsigned i=1; i<=n; ++i ) a += log10(i+0.0); return (unsigned)pow( 10.0, a-floor(a) ); } // 方法2 // 保留6位有效数 unsigned digital6valid( unsigned n ) { unsigned long long a = 1; for( unsigned i=1; i<=n; ++i ) { a *= i; if(a>=100000000000) a/=1000000; else if(a>=10000000000) a/=100000; else if(a>=1000000000) a/=10000; else if(a>=100000000) a/=1000; else if(a>=10000000) a/=100; else if(a>=1000000) a/=10; } if(a>=100000) a/=100000; else if(a>=10000) a/=10000; else if(a>=1000) a/=1000; else if(a>=100) a/=100; else if(a>=10) a/=10; return (unsigned)a; } // 方法3 // 直接将1000位阶乘的结果保存着,可用于验证其它算法是否正确 unsigned map1001( unsigned n ) { static const char* rs = "11262175433346812361251261413828282131528316215216318421742185311853211864321118754332221111111199999999111111111222334568911123346811123569112358112358123471124712359124712361136123612471259136125113713612512512412412412512512613714925127149251382513825138251392614139261413127251413138272615141313139282727262626262626262727272829313131415152728213141516283131516293141628314162931527314162141621416214162141731529316214283162152941831621521429418317317316316316316316317317318319421421521631831942163173115216319421631942163115217421631152184217421732163216321632163216321742184219531163217421953217421163218531174211642196321953219632116421174211853219642117532116432196421185321185421196432117432118542211753211965321197532111754321186432111864321118643221196543211186432211186543211197643221119764332211187543322111976543222111986543322111118765433222111198765433222111111876654433222211111198766544433322221111111198876655544433332222222111111111111119988877776666655555554444444444444444444444"; return rs[n]-'0'; } int main(void) { for( unsigned i=0; i<=1000; ++i ) { if( digital6valid(i) != map1001(i) ) { printf( "[ERROR] %u! = %u...\n", i, sterling(i) ); break; } } return 0; }