Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Very simple program in C, help needed

  1. Jan 24, 2012 #1

    fluidistic

    User Avatar
    Gold Member

    So this isn't for homework. Basically I have a program in fortran 90 that computes an approximation of pi using a very non efficient method. So that it can do about 10^8 operations and still doesn't converge that much wich is what I'm looking for.
    I want to write this program in C too, but I've never written any program in C yet, not even the hello world. I want to compare the speed of both programs for the task of approximating pi via a product.
    In fortran the code is
    Code (Text):
    program pi
    implicit none

    real (8) ::p
    integer ::n,m

    write(*,*)'Enter n please'
    read(*,*)n

    p=1d0
    do m=1,n
    p=p*((2d0*m)**2d0)/((2d0*m)**2d0-1d0)
    end do
    write(*,*)"The approximation of pi is",2*p
    end program
    Executing it gives:
    Code (Text):
     Enter n please
    1000000
     The approximation of pi is   3.1415918681920378  
    I'd like to have the same characteristics for the program in C. Namely, I want to be able to enter n whenever I execute the program.
    I do not know how to assignate a value to a real number (float in C?) that can change. So #assignate wouldn't work I think. I'd need this in order to start the product, p must equal 1.
    I've been through some pages of a tutorial on the internet, so far my program is:
    Code (Text):
    #include <stdio.h>
    using namespace std;
    int n,m
    float p
    m=1
    int main()
    {
     prinf ("Enter n.\n");
     scanf( "%d", n );
      getchar();
      return 0;
      p=1;
      do{
       
      }   while(m<n);
     
    }
    I know the lines "m=1" and "p=1" are probably wrong. Any help is appreciated.
     
  2. jcsd
  3. Jan 24, 2012 #2
    First off, take out using namespace std, that is C++, also return 0; goes at the end of your main function returning success and control back to OS. Then your scanf needs an ampersand before your variable ex: scanf("%d",&n);
     
    Last edited: Jan 24, 2012
  4. Jan 24, 2012 #3
    Also most of your lines lack semicolons at the end, also "m=1" is outside of any function, also your do {} while; loop, there is nothing in between { and }, this means the loop will never end because the result of the conditional will never change.

    The C equivalent of
    Code (Text):
    do m=1,n
    <stuff>
    end
     
    is
    Code (Text):
    for(int m = 1; m <= n; m++) {
    <stuff>
    }
    And the C equivalent of a**b is pow(a,b); (you will need to include math.h)

    I bet you can find a computer program that just plain translates fortran into C.
     
  5. Jan 24, 2012 #4

    fluidistic

    User Avatar
    Gold Member

    Ok guys thanks a lot!
    My code is now
    Code (Text):
    #include <stdio.h>
    #include <math.h>

    int main()
    {
      int n,m;
    float p;
     prinf ("Enter n.\n");
     scanf( "%d", &n );
      getchar();

      p=1;
      for( m = 1; m <= n; m++) {
    p=p*(pow((2*m),2)/(pow((2*m),2)-1));
    }
    prinf("The approximation of pi is\n",p);

    getchar();
    }
    To Coin: yes I know I had put nothing between the do while because I was unsure on how to assignate values to p, n, m, etc. I think it's good to learn the basics of C, I wouldn't like to use a program to do this. :)
    When I try to compile, I get
    Code (Text):
    /tmp/ccppllAb.o: In function `main':
    pi.c:(.text+0x11): undefined reference to `prinf'
    pi.c:(.text+0x91): undefined reference to `prinf'
    collect2: ld returned 1 exit status
     
    So it seems something's wrong with my prinf statement.
     
  6. Jan 24, 2012 #5
    It's "printf." :P
     
  7. Jan 24, 2012 #6
    Also on this line "prinf("The approximation of pi is\n",p);"
    it is printf like Tyler said, also you want to display your variable so you have to use %f inside your quotations to display a float, you can truncate the decimal places if you want ex. printf("The approximation of pi is %.4f\n",p); and you dont need the getchar(); there you can put it at the end of your code to keep the console window open if you are using dev-c++ or some other IDE that doesnt keep it open, btw what compiler are you using? EDIT: nvm I see why you have it there to take in the '\n' character after first scanf
     
    Last edited: Jan 24, 2012
  8. Jan 24, 2012 #7

    fluidistic

    User Avatar
    Gold Member

    Ok guys thanks, my program now works.
    It's currently:
    Code (Text):
    #include <stdio.h>
    #include <math.h>

    int main()
    {
      int n,m;
    float p;
     printf ("Enter n.\n");
     scanf( "%d", &n );


      p=1;
      for( m = 1; m <= n; m++) {
    p=p*(pow((2*m),2)/(pow((2*m),2)-1));
    }
    printf("The approximation of pi is %.8f\n",2*p);

    getchar();
    }
    However when I execute it, I get:
    Code (Text):
    Enter n.
    1000000
    The approximation of pi is 3.14132977
    But with the same n under fortran, I reached 3.1415918681920378 which is much closer to the "real" value of pi.
    Also in C, when I increase n even more than 10^6, I get the same result, 3.14132977. Hmm... what's going on?
     
  9. Jan 24, 2012 #8
    try making p a double instead of a float ex double p; then in your printf statments use %lf to display a double
     
  10. Jan 24, 2012 #9

    fluidistic

    User Avatar
    Gold Member

    Ok thanks.
    Now I get
    Code (Text):
    pi.c: In function ‘main’:
    pi.c:7: error: two or more data types in declaration specifiers
    Line 7 is p=1; line.
     
  11. Jan 24, 2012 #10
    post all of your code
     
  12. Jan 24, 2012 #11

    fluidistic

    User Avatar
    Gold Member

    Code (Text):
    #include <stdio.h>
    #include <math.h>

    int main()
    {
      int n,m;
    float double p;
     printf ("Enter n.\n");
     scanf( "%d", &n );


      p=1;
      for( m = 1; m <= n; m++) {
    p=p*(pow((2*m),2)/(pow((2*m),2)-1));
    }
    printf("The approximation of pi is %lf\n",2*p);

    getchar();
    }
     
  13. Jan 24, 2012 #12
    take off float on line 7 it should just be double

    Code (Text):
    int main()
    {
      int n,m;
    double p;
     printf ("Enter n.\n");
     scanf( "%d", &n );


      p=1;
      for( m = 1; m <= n; m++) {
    p=p*(pow((2*m),2)/(pow((2*m),2)-1));
    }
    printf("The approximation of pi is %.10lf\n",2*p);

    getchar();
        return 0;
    }
    that gave me the same answer as your fortran program
     
  14. Jan 24, 2012 #13

    fluidistic

    User Avatar
    Gold Member

    Ok thank you very much for all.
    For C, n=10^9 around 19 s. (3.1415926423)
    For fortran, n=10^9 around 26 s.(3.1415926422888196)
    I don't know if it's because fortran kept more digits, in all cases I'm very impressed.
     
  15. Jan 24, 2012 #14
    you can always move out to 16 decimal places also just change .10lf to .16lf
     
  16. Jan 24, 2012 #15

    jhae2.718

    User Avatar
    Gold Member

    You could try a long double for more precision.
     
  17. Jan 24, 2012 #16
    If you're thinking about doing some numerical stuff in C, you might want to check out GMP. It's a library that allows you to use arbitrary precision integers and reals.
     
  18. Jan 24, 2012 #17

    Mark44

    Staff: Mentor

    I would do the loop without using pow(), since all you're doing is squaring a number (which is equivalent to multiplying it by itself).

    I have introduced another variable, but haven't declared it. Your code would need to declare this variable.

    Code (Text):
    for( m = 1; m <= n; m++)
    {
        value = 2.0 * m;
        p = p * value * value / (value * value - 1.0) ;
    }
     
    This code has at least two advantages:
    1) It's simpler, by computing an intermediate value first, which makes the 2nd line easier to read, and easier to spot syntax errors caused by unmatched parentheses.
    2) It uses multiplication and division, which can be performed more quickly than a relatively more expensive call to pow(). pow() should never be called if all you're doing is squaring a number.

    I would also change the type of p from float to double. A float only has 6 or 7 decimal places of precision, so that will affect your answer.
     
  19. Jan 24, 2012 #18

    fluidistic

    User Avatar
    Gold Member

    I now get (with 16 decimals) 3.1415926422818243, still 19 s.
    I'll retry tomorrow and I'll check out your posts guys more in details, it's 2:26 am currently... must sleep.
     
  20. Jan 24, 2012 #19

    Mark44

    Staff: Mentor

    Some compilers support long double, and some don't, or at least didn't in the past. I haven't looked into this recently, so it could be that modern compilers support long doubles.

    A compiler that supports long double stores the number in 10 bytes, which is conveniently the same size as the registers in the floating point unit.
     
  21. Jan 24, 2012 #20

    Mark44

    Staff: Mentor

    Is that 19 seconds? Still, if you're using float, you don't have more than 6 to 7 digits of precision after the decimal point. From the calculator, [itex]\pi[/itex] is 3.1415926535897932384626433832795
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Very simple program in C, help needed
Loading...