C 语言中使用 long double 计算 pi
我在计算 pi 时遇到问题,当我将 long double 放入变量中时,会出现一个很大的数字,但不是正确的值,如果您用 double 更改 calcf 函数,它就可以工作。 我的代码:
#include <stdio.h>
#include <math.h>
long double calc(int n, double denominador) {
//printf("%lf e",(pow(-1,n))/denominador);
//printf("%d\n",(denominador));
long double var = (long double) ((4.0*(pow(-1.0,n)))/denominador);
printf("%Lf\n",(long double)var);
return var;
}
double calcf(int n, int denominador) {
//printf("%lf e",(pow(-1,n))/denominador);
//printf("%d\n",(denominador));
double var = (4.0*(pow(-1.0,n)))/denominador;
//printf("%lf",var);
return var;
}
int main() {
int NUMERO = 100000000;
long double pi = 4L;
double pif = 4;
int i;
int n=1;
printf("%d e %d",sizeof(double),sizeof(long double));
for (i=3;i<NUMERO;i+=2) {
pi += calc(n,(double) i);
//pif += calcf(n,i);
n++;
}
printf("PI: %1.50Lf\n",pi);
}
我做错了什么?
谢谢。
i have a problem in calc of pi, when i put long double in variable appears a big number, but not the correct value, if you change for calcf function with double it works.
My code:
#include <stdio.h>
#include <math.h>
long double calc(int n, double denominador) {
//printf("%lf e",(pow(-1,n))/denominador);
//printf("%d\n",(denominador));
long double var = (long double) ((4.0*(pow(-1.0,n)))/denominador);
printf("%Lf\n",(long double)var);
return var;
}
double calcf(int n, int denominador) {
//printf("%lf e",(pow(-1,n))/denominador);
//printf("%d\n",(denominador));
double var = (4.0*(pow(-1.0,n)))/denominador;
//printf("%lf",var);
return var;
}
int main() {
int NUMERO = 100000000;
long double pi = 4L;
double pif = 4;
int i;
int n=1;
printf("%d e %d",sizeof(double),sizeof(long double));
for (i=3;i<NUMERO;i+=2) {
pi += calc(n,(double) i);
//pif += calcf(n,i);
n++;
}
printf("PI: %1.50Lf\n",pi);
}
What i'm doing wrong?
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
嗯,这个程序有很多问题;但最糟糕的是你使用的是格雷戈里级数,它几乎是最慢的算法。你甚至不会得到双精度,更不用说长双精度了。您必须让它运行大约 1016 步才能获得两倍。
数学家使用 -1n 来表示交替符号,这在这种情况下很好,但使用
pow()
来计算它就很愚蠢,特别是因为它是一个浮点手术。相反,使用从 -1 开始的整数并继续执行i = -i
。您需要更加小心您的类型和常量。
4L
是一个长整型,而不是一个长双精度型。您需要4.0L
。当然,编译器无论如何都会强制转换它,但这是不好的做法。当您的目标是长双精度时,您正在使用普通的旧双精度常数,例如 4.0。每一步都将所有内容乘以 4.0 也是愚蠢的。你可以在最后做。
Well, this program has many issues; but the worst one is that you're using Gregory's series, which is just about the slowest algorithm out there. You're not even going to get double precision with that, let alone long double. You would have to let it run through about 1016 steps just for double.
Mathematicians use −1n to indicate an alternating sign, which is fine in that context, but using
pow()
to calculate it is just silly, especially since it's a floating point operation. Instead, use an integer that starts at -1 and keep doingi = -i
.You need to be more careful with your types and constants.
4L
is a long integer, not a long double. You want4.0L
. Of course the compiler casts it anyway, but it's bad practice. You're using plain old double constants like 4.0 when you're aiming for long double precision.It's also silly to keep multiplying everything by 4.0 at every step. You can just do it at the end.
pow()
接受并返回双精度数。您需要使用 powl() 来代替,它接受并返回长双精度数。否则,您只是将双精度型转换为长双精度型,并且不会获得任何精度。pow()
takes and returns doubles. You need to usepowl()
which takes and returns long doubles instead. Otherwise you're just casting a double to long double and are not gaining any precision.