usage of powl() function

This is a discussion on usage of powl() function within the C Programming forums, part of the General Programming Boards category; Hi, this is probably a very simple problem however I cannot get a valid output from the powl() function. everytime ...

  1. #1
    Registered User
    Join Date
    Sep 2010
    Posts
    4

    usage of powl() function

    Hi, this is probably a very simple problem however I cannot get a valid output from the powl() function. everytime I run it, it gives an output of 0.00. This is probably just a simple usage problem but I can't work out how to raise long double variables to the power of other long double variables. My program is an iterative calculation of pi using 4*(4arctan(1/5)-arctan(1/239). I know you could use the inbuilt arctan functions in math.h but i wanted to make it iterative. I have read the man pages on pow()/powf()/powl() and scoured google but can't get it to work.

    sorry for if i'm being thick.

    Code:
    /*
     program works by working out pi as 4*(4arctan(1/5)-arctan(1/239)
    it approximates arctan(z) as (z^1)/1-(z^3)/3+(z^5)/5-... 
    */
    
    #include <stdio.h>
    #include <stdbool.h>
    #include <math.h>
    
    int main (int argc, const char * argv[]) {
        long double pi, arctan1, arctan2, divisor;
    	bool sign;
    	int count;
    	sign = 0;
    	count = 0;
    	divisor = 1;
    	printf("\n");
    	while (count < 100) {
    		
    		if (sign == 0) 
    			
    		{
    			arctan1 += (( powl( (1/5) , divisor))/divisor );
    			arctan2 += (( powl ( (1/239) , divisor))/divisor );
    			sign = 1;
    			
    		}
    		
    		else 
    			
    		{
    			arctan1 -= (( powl ( (1/5) , divisor))/divisor );
    			arctan2 -= (( powl ( (1/239) , divisor))/divisor );
    			sign = 0;
    			
    		}
    		
    		
    		pi=4*((4*arctan1)-arctan2);
    		
    		printf("\r%.050Lf", pi);
    		count++;
    		divisor +=2;
    		
    	}
    	
    	return 0;
    	
    }

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,202
    (1/5) is dividing two int's, and gives a result of type int, and will have the value of zero. Similarly for (1/239).

    This means that, on each of your lines where you call powl(), the first argument it is receiving is zero.

    Zero raised to any non-zero power is zero, hence .....
    Right 98% of the time, and don't care about the other 3%.

  3. #3
    Registered User
    Join Date
    Sep 2010
    Posts
    4
    Ok thanks a lot, i've changed it to using decimals instead of dividing two ints. how would i set it to divide them by using a floating point calculation in powl()?

    Code:
    /*
     program works by working out pi as 4*(4arctan(1/5)-arctan(1/239)
    it approximates arctan(z) as (z^1)/1-(z^3)/3+(z^5)/5-... 
    */
    
    #include <stdio.h>
    #include <stdbool.h>
    #include <math.h>
    
    int main (int argc, const char * argv[]) {
        long double pi, arctan1, arctan2, divisor;
    	bool sign;
    	int count;
    	
    	sign = 0;
    	count = 0;
    	divisor = 1;
    	printf("\n");
    	while (count < 100) {
    		
    		if (sign == 0) 
    			
    		{
    			arctan1 += (( powl( (0.2) , divisor))/divisor );
    			arctan2 += (( powl ( (0.0041841) , divisor))/divisor );
    			sign = 1;
    			
    		}
    		
    		else 
    			
    		{
    			arctan1 -= (( powl ( (0.2) , divisor))/divisor );
    			arctan2 -= (( powl ( (0.0041841) , divisor))/divisor );
    			sign = 0;
    			
    		}
    		
    		
    		pi=4*((4*arctan1)-arctan2);
    		
    		printf("\r%.050Lf", pi);
    		count++;
    		divisor +=2;
    		
    	}
    	
    	return 0;
    	
    }

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,202
    It's got nothing to do with powl().

    The code
    Code:
       double x = 1/5;
    will set x to zero for the same reason.

    To change that, make one of the terms in the expression a double. For example;
    Code:
       double x = 1.0/5;
    or
    Code:
       double x = 1/5.0;
    The result of the first is that the int 5 is converted to double, and then the division is done. In the second example, the int 1 is converted to double, and then the division is done.

    Look up the implicit type promotion (or conversion) rules in C for a more detailed explanation.
    Right 98% of the time, and don't care about the other 3%.

  5. #5
    Registered User
    Join Date
    Sep 2010
    Posts
    4
    thank you very much for your help, as you've probably guessed, i'm extremely new to C programming.
    ok last question (sorry)
    how can I implement more precision than long double, because after 20 iterations it doesn't seem to change the value of pi. i'm guessing this is due to rounding due to it running out of usable bits in memory. (maybe i'm wrong)

    i've heard about __float128 but i'm not sure if this would be tricky to implement, there's not much i can find about it.

    Code:
    /*
     program works by working out pi as 4*(4arctan(1/5)-arctan(1/239)
    it approximates arctan(z) as (z^1)/1-(z^3)/3+(z^5)/5-... 
    */
    
    #include <stdio.h>
    #include <stdbool.h>
    #include <math.h>
    
    int main (int argc, const char * argv[]) {
        long double pi, arctan1, arctan2, divisor, a, b;
    	bool sign;
    	int count;
    	a = (1.0)/(5.0);
    	b = (1.0)/(239.0);
    	sign = 0;
    	count = 0;
    	divisor = 1;
    	printf("\n");
    	while (count < 2000) {
    		
    		if (sign == 0) 
    			
    		{
    			arctan1 += (( powl ( a , divisor))/divisor );
    			arctan2 += (( powl ( b , divisor))/divisor );
    			sign = 1;
    			
    		}
    		
    		else 
    			
    		{
    			arctan1 -= (( powl ( a , divisor))/divisor );
    			arctan2 -= (( powl ( b , divisor))/divisor );
    			sign = 0;
    			
    		}
    		
    		
    		pi=4*((4*arctan1)-arctan2);
    		
    		printf("%.0100Lf\n", pi);
    		count++;
    		divisor +=2;
    		
    	}
    	printf("\n");
    	return 0;
    	
    }

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,202
    All native floating point types (float, double, long double) have finite size, therefore finite precision. There is no native C type that has infinite size (which would be the requirement for infinite precision).

    If you want more floating point precision than long double, you are going beyond what standard C supports. You will either need to use a third-party library that supports greater precision or usecompiler-specific extensions.

    High precision floating point libraries are available (eg the MPFR if you are using gnu compilers) but their usage is a bit more involved than is the case with your code - I suggest getting more expertise with C before mucking about with such things.

    ___float128 is a type supported by some compilers (i.e. it is a compiler specific extension). In practice ___float128 is sometimes a pseudonym for long double (long double is often a 16 byte floating point type, each byte has 8 bits, 16*8 = 128).
    Right 98% of the time, and don't care about the other 3%.

  7. #7
    Registered User
    Join Date
    Sep 2010
    Posts
    4
    thanks a lot for the help. i've found it extremely useful. I will continue learning C programming before I move onto another language or compiler extensions.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling C in Visual Studio 2005
    By emanresu in forum C Programming
    Replies: 3
    Last Post: 11-16-2009, 03:25 AM
  2. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  3. dllimport function not allowed
    By steve1_rm in forum C++ Programming
    Replies: 5
    Last Post: 03-11-2008, 03:33 AM
  4. Problem with Visual C++ Object-Oriented Programming Book.
    By GameGenie in forum C++ Programming
    Replies: 9
    Last Post: 08-29-2005, 11:21 PM
  5. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 09:18 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21