特林斯公式如何计算N! 的最高位

发布于 2022-09-03 00:55:53 字数 992 浏览 15 评论 0

如果是一个非常大的N <10000000 那么计算出来的N!也是非常大的,现在只需要知道最高位的数字。
通过斯特林公式可以计算。
特林斯公式:
图片描述 (公式1)
如下是算法:

result = 0.5* log(2*PI*(double)n)/log(10.0) + (double)n* log((double)n/E)/log(10.0);
result -= (int)result;
first_number = exp(result * log(10.0));

以上算法代码计算通过公式表示:
图片描述 (公式2)
目前已知通过如下计算可以得到最高位:
图片描述 (公式3)
剩下的就是求N!,虽然N!可以通过特林斯计算,但是计算结果非常大。计算机直接计算会溢出结果,如下执行结果:
图片描述
可以看出当执行到180的时候结果都已经溢出。
原因应该是在计算N! 的时候结果直接存储在计算机导致空间不足。
我所不明白的是为什么(公式2)的算法就可以直接计算出结果不溢出,且正确(当然数字过小的话也会有错误,比如0,1,2,3,7,8结果将不正确)。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

望喜 2022-09-10 00:55:53

最终是通过以10为底的对数log10(xxx)来求其最高位,这个你理解吧?他上面就是通过对数变换把求以10为底的对数转为以e为底的对数 aka: ln(yyy)

云胡 2022-09-10 00:55:53

首先,胡须佬头,已经说的很明白了,原理就是他所说的那个,把原来用lg去求的问题,转换为了ln去求。

我还是给你贴张tu吧:(喜欢数学的都是好样的)
C语言程序

看到啦,其实上面已经验证过了,如果要求5014的最高位,那么可以写成:
最高位 = 5014 / (取整数)1g(5014); (注意类C语言里面,除法,会进行整型截断)

ok,再说正事儿,你那个特林斯公式,假设拿到的阶乘的近似值为X (一大串不管了,简单点儿叫X),

如果想拿到这个数的最高位h,那么有如下计算:

h = X / (int)lgX;

此时,通过特林斯公式,X 已求得,

计算一下“lgX的整数部分”就可以了。

先笼统的算(先不求整部和小数部分,直接算lgX)

lgX = lnX / ln10 (就是你上面把特林斯公式带进去求值的那个式子,哦,你的图还算错了)
得到lgX= result (我化简过了,不信你把那个特林斯公式化简成)

到这里,就明白了,拿到result的整数部分,就能救出lgX的整数部分了,也就能求出最高位h.

而不是你说的“拿到小数部分”。

最后,根据你提供的特林斯公式,得到阶乘factorial的值为:
X 约等于 e^(ln10 * result的整数部分); (你可以自己从特林斯的公式变形到这一步看看)

貌似也不是你所说的
first_number = exp(result * log(10.0));

再有问题,在讨论?贴出你最终的结果?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文