0

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.

kavain
  • 451
  • 2
  • 8
  • 20

2 Answers2

3

pow() takes and returns doubles. You need to use powl() which takes and returns long doubles instead. Otherwise you're just casting a double to long double and are not gaining any precision.

Tom Zych
  • 13,329
  • 9
  • 36
  • 53
Splat
  • 753
  • 3
  • 10
  • i try this but the problem is other – kavain Aug 05 '11 at 04:24
  • 2
    @thamerhatem If you want to get more help from people here, you need to provide more information than "it didn't work", especially with a program that takes many minutes to run. I think there are probably two issues here. First, I don't think this algorithm converges to a point where there will be a significant difference between double and long double in the number of iterations you're using. Second, floating point math is fraught with potential for inadvertently causing errors. See this Wikipedia article for more information about it: http://en.wikipedia.org/wiki/Floating_point – Splat Aug 06 '11 at 18:32
3

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 doing i = -i.

You need to be more careful with your types and constants. 4L is a long integer, not a long double. You want 4.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.

Tom Zych
  • 13,329
  • 9
  • 36
  • 53