0

我试图用 C 表示以下数学表达式:

P(n) = (n!)(6^n)

n= 156 时,程序应该计算表达式的答案。我试图用 C 语言创建程序,但它无法产生答案。答案大约是 10^397。该程序使用 2 个对数恒等式。它还利用斯特林近似来计算大阶乘。

我怎样才能让它产生正确的答案,你对我如何改进代码有什么建议吗?(我对编程很陌生):

#include <math.h>
typedef unsigned int uint;

int main()
{
uint n=156;                               // Declare variables
double F,pi=3.14159265359,L,e=exp(1),P;
F = sqrt(2*pi*n) * pow((n/e),n);          // Stirling's Approximation Formula
L = log(F) + n*log(6);                    // Transform P(n) using logarithms - log(xy) = log(x) + log(y) and log(y^n) = n*log(y)
P = pow(e,L);                             // Transform the resultant logarithm back to a normal numbers
}

谢谢!:)

4

4 回答 4

4

大多数 C 实现中的整数和浮点变量都不能支持这种数量级的数字。典型的 64 位双精度值会上升到 10 308之类的值,但在这个量级上会严重损失精度。

您需要所谓的“bignum 库”来计算它,这不是标准 C 的一部分。

于 2014-12-02T18:51:38.247 回答
1

一种想法是使用long double类型。它的精度无法保证,因此它可能足够大,也可能不足以满足您的需求,具体取决于您使用的编译器。

替换doublelong doubleexpl为所有数学函数 ( , logl, powl, )添加“l”(小写 L)后缀sqrtl。编译时启用 C99,因为long doubleC99 中提供了数学函数。它使用 GCC 4.8.1 对我有用。

#include <math.h>
#include <stdio.h>
typedef unsigned int uint;

int main()
{
    uint n=156;                               // Declare variables
    long double F,pi=3.14159265359,L,e=expl(1),P;
    F = sqrtl(2*pi*n) * powl((n/e),n);          // Stirling's Approximation Formula
    L = logl(F) + n*logl(6);                    // Transform P(n) using logarithms - log(xy) = log(x) + log(y) and log(y^n) = n*log(y)
    P = powl(e,L);                             // Transform the resultant logarithm back to a normal numbers
    printf("%Lg\n", P);
}

我明白了1.83969e+397

于 2014-12-02T19:35:37.780 回答
0
#include <math.h>
#include <float.h>
typedef unsigned int uint;

int main()
{
uint n=156;                               // Declare variables
long double F,pi=3.14159265359,L,e=expl(1),P;
F = sqrtl(2*pi*n) * powl((n/e),n);          // Stirling's Approximation Formula
L = logl(F) + n*logl(6);                    // Transform P(n) using logarithms - log(xy) = log(x) + log(y) and log(y^n) = n*log(y)
P = powl(e,L);                             // Transform the resultant logarithm back to a normal numbers
printf("%d\n", LDBL_MAX_10_EXP);
}
于 2014-12-02T19:55:59.633 回答
0

粗略地说,在 C 中,双精度数表示为一个基数的幂。如前所述,最大值大约为 1E308,但是当您获得越来越大的数字(或越来越小)时,您会失去精度,因为基数的位数是有限的,并且不能始终以这种方式准确表示。

有关详细信息,请参阅http://en.wikipedia.org/wiki/Double-precision_floating-point_format

于 2014-12-02T19:04:52.683 回答