1. 程式人生 > >斯特林(Stirling)公式 求大數階乘的位數

斯特林(Stirling)公式 求大數階乘的位數

href put || tdi code const 但是 body https


我們知道整數n的位數的計算方法為:log10(n)+1
n!=10^m
故n!的位數為 m = log10(n!)+1

lgN!=lg1+lg2+lg3+lg4+lg5+....................+lgN;

但是當N很大的時候,我們可以通過數學公式進行優化:(即Stirling公式)

N!=sqrt(2*pi*N)*(N/e)^N;(pi=3.1415926=acos(-1.0),e=exp(1))

lgN!=(lg(2*pi)+lgN)/2+N*(lgN-lge);

斯特林公式可以用來估算某數的大小結合lg可以估算某數的位數,或者可以估算某數的階乘是另一個數的倍數。

例題

https://www.nowcoder.net/acm/contest/75/A

題意 求解n的階乘八進制下的位數

n!=8^res n!=e^m

res=log8(n!) m=loge(n!)

log8(n!)= loge(n!)/loge(8) res = m/loge(8)換底公式

m=loge(2*pi*n)/2+n*loge(n/e)

AC代碼

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include 
<algorithm> #include <string> #include <queue> #include <map> #include <vector> using namespace std; const int maxn = 1e6+10; const int inf = 0x3f3f3f3f; const double e = exp(1); const double pi = acos(-1.0); const double epx = 1e-10; typedef long long ll; int main() { ll t; scanf(
"%lld",&t); while(t--){ ll n; scanf("%lld",&n); if(n==0||n==1){ puts("1"); continue; } double res = (log(2*pi*n)/2.0+n*log(n/e))/log(8)+1; printf("%lld\n",(ll)res); } return 0; }

斯特林(Stirling)公式 求大數階乘的位數