#include <stdio.h>

float pows(float,float);

int main()
{
	float num,base;
	printf("enter base followed by power integer.");
	scanf("%f %f",&base,&num);

	printf("%f ",pows(base,num));


	return 0;
}

float pows(float base,float n)
{

	if(n==0)
	  return(1);
	else if(base==0)
	  return(0);
	else
		for(;n>=1;n--)
		{   return(base*pows(base,n-1));/*recursive*/

			}



}

Other than it doesn't work properly

yeah.I know it's not perfect.But couldn't find other bugs 'cept its smaller range.
See,that's why I posted this in discussion thread.

Or is this an ego-post?

No,this is not "an ego-post".

do you have a question?

The thing is ,I didn't came up with any while posting.
So I just posted the code(looking for advice).

%f and float n does not look integer to me, like your prompt and algorithm suggests.

I was using int(egers) before,float was used to increase it's range.
I overlooked this line

printf("enter base followed by power integer.");

while changing to float.

Also you are doing both iteration and recursion same time, chose which one.

Am I supposed to do either iteration or recursion only(i.e.no need to both)?

It has got MAJOR precision issues.
How do I make it accept negative "power" argument
pows(100,-2) gives nothing.

Your algorithm can not deal with fractions, so you should take long, not float argument. But I doubt that C can deal with bigger than int range of powers if you are not dealing with very small numbers (which also would could take quite a while as you are recursing every single number from n to 1).

For efficiency you maybe should take a look at least for the recursive power algorithm:
http://www.catonmat.net/blog/mit-introduction-to-algorithms-part-two/

As for negative powers, how were you teached to do them in school with positive powers? You must also do that adaptation to the recursive algorithm's pseudocode.

Edited 5 Years Ago by pyTony: n/a

looking for advice).

Then why didn't you say so? Posting only code says "Look at my code! Ain't it great?" That's an ego-post. If you simply added "I'm looking for advice on making this code better" you would get more useful responses right away.

I trimmed the precious one a little bit and used double instead of float.

#include <stdio.h>




double pows(double,double);

int main()
{
	double num,base;
	printf("enter base followed by power.");
	scanf("%lf %lf",&base,&num);

	printf("%lf ",pows(base,num));


	return 0;
}

double pows(double base,double n)
{
    

	if(base==0)
		return(0);
	else if(n==0)
		return(1);
	else if(n>=1)
		{
			return(base*pows(base,n-1));/*for positive powers*/

			}
	



}

To make it work with negative powers I was thinking like this...

else if(n<=-1)
		{   n=abs(n);/* abs()--->#include <complex.h> */
	        
			return((base)/pows(base,n+1));/*for negative powers*/
	        }

But it doesn't work that way.Here abs(n) returns zero.
something's wrong with the implementation?what should I do then?

By the way I tried the algorithm suggested inhttp://www.catonmat.net/blog/mit-int...thms-part-two/
It worked fine (but not with long arguments) .Anyways,thanks for that pyTony.

It also doesn't work if you input
12 2.5
An infinite loop is not an appropriate answer either.

Hint: a**-1 == 1/a

yeah, that's what I did here.

double pows(double base,double n)
{


	if(base==0)
		return(0);
	else if(n==0)
		return(1);
	else if(n>=1)
		{
			return(base*pows(base,n-1));/*for positive powers*/

			}
	else if(n<=-1)
		{   n=-n;

			return((base)/pows(base,n+1));/*for negative powers*/
	        }



}

for positive value:
pows(10,22) gives 10000000000000000000000.000000
but pows(10,23) gives 99999999999999992000000.000000------>(Now, where did that come from?)
for negative value:
pows(10,-6) gives 0.000001
pows(10,-7) gives 0.000000------>(how to increase its range?)

It also doesn't work if you input
12 2.5

Yeah I'll deal with those kinda fractions later.First negative exponentiation.

Change the format to printing of the result to %g (scientific notation).
I do not understand why do you write negative powers so as you write instead of simple 1./pows(base, -n), even it seems to work.

I do not understand why do you write negative powers so as you write instead of simple 1./pows(base, -n), even it seems to work.

I didn't understand what you're trying to say.Can you "please" show it in c code.

Now, we need to handle powers in fractions like 1/2,2/3,5/7...similarly
-1/2,-3/2,-3/7...etc.
Can anyone help me figure out the solution,
OR suggest a better algorithm.

Generally if you deal with non-integer numbers as powers you would use exponentiation with multiplication of logarithms.

My comment was about this 'interesting' lines:

else if(n<=-1)
		{   n=-n;

			return((base)/pows(base,n+1));/*for negative powers*/
	        }

which mean:

else if(n<=-1) return 1./pows(base,-n);

and in main:

printf("%g ",pows(base,num));

Edited 5 Years Ago by pyTony: n/a

Yeah thanks pyTony, I really appreciate that.Now it's crystal clear to me.

For the power of fractions like 1/2,2/3,5/2 etc:
If we had to do like pows(12,2.5)
we could do like this:- 12 ^ 5/2 can be written as (12 ^ 5)^1/2
and (something)^1/2 means sqrt of (something).
Hence we need an algorithm to find not just square root or cube root but nth root of a number.Can anyone help me with that?

Used a code in here to produce sqrt and rest is here.

#include <stdio.h>
#include "sqroot.h"




double pows(double,double);
double pows_f(double,int,int);

int main()
{
	double base,num;
	int num_rt,denum_rt;
	printf("enter Base followed by Numerator and then Denominator\n.");
	scanf("%lf %d %d",&base,&num_rt,&denum_rt);

	printf("%lf ",pows_f(base,num_rt,denum_rt));


	return 0;
}

double pows(double base,double n)
{


	if(base==0)
		return(0);
	else if(n==0)
		return(1);
	else if(n>=1)
		{
			return(base*pows(base,n-1));/*for positive powers*/

			}
	else if(n<=-1)
		{

			return(1/pows(base,-n));/*for negative powers*/
				        }
	else
		printf("error!");
		return(0);



}

double pows_f(double base,int num,int denum)/* num means numerator & denum means denomenator*/
{
	double root_ed,pows_ed;/* variables to store root(ed) value & pows(ed) value*/

	pows_ed=pows(base,num);
	return root(pows_ed,denum);
}

pows_f(5,1,2)--->5^1/2 =2.236068
pows_f(17,3,2) = 70.092796

pretty close .

Attachments
#include <stdio.h>
 
inline double _abs(double x) { return x < 0 ? -x : x; }
double _pow(double x, int e)
{
	double ret = 1;
	for (ret = 1; e; x *= x, e >>= 1)
		if ((e & 1)) ret *= x;
	return ret;
}
 
double root(double a, int n)
{
	double x0, x1 = 1;
 
	do {	x0 = x1;
		x1 = ((n - 1) * x1 + a / _pow(x1, (n - 1))) / n;
	} while (_abs(x0 - x1) > _abs(x1) * 1e-14);
 
	return x1;
}
 
//int main()
//{
//	double x = _pow(3.14159, 15);
//	printf("root(%g, 15) = %g\n", x, root(x, 15));
//	return 0;
//}

The above code doesn't need variable root_ed,I forgot to remove it
(man!What was I thinking).and also to use %g(scientific format).

Alright.Everything's fine except one thing.
I need pows_f to accept usually two arguments(sometimes three).Can we do that in C?
If I need to find out 25^13 I need to enter as pows_f(25,13,1)
Can we make the third argument optional(i.e. should be given only when required)
for e.g to find 25^13 as pows_f(25,13) only and to find 25^3/4 as pows_f(25,3,4).

I looked at the example there.It seems totally different case than mine.
I don't know How to use it in my code.It would be great help if you'd show me an example of it(a case like mine).

After reading further and going over the hurdle of dropped underlines from my googled source, I noticed that in C there is not support for automatic count of parameters. So it is only usefull if you give is_rational as extra parameter, which kind of beats the purpose. So you are better of just having two versions of funcition or maybe having the power as string and detecting '/' in it or not and parsing accordingly.

Here it is.

#include <stdio.h>
#include "sqroot.h"




double pows(double,double);
double pows_f(double,int,int);

int main()
{
	double base,num;
	char power[10];
	int num_rt,denum_rt;
	int i,j,is_rational;
	printf("enter Base followed by power\n.");
	scanf("%lf %s",&base,power);

	for (i=0;i<=sizeof(power);++i)
		{
			if(power[i]=='/')  /*rational*/
				{

					num_rt=power[0]-48;
					for(j=0;j+1<i;j++)
						{
							num_rt=num_rt*10+(power[j+1]-48);/* ascii value of character 1 is 49*/

						}
					denum_rt=power[i+1]-48;
					for(j=i+1;j+1<strlen(power);j++)
						{
							denum_rt=denum_rt*10+(power[j+1]-48);/*similar to num*/
						}

					is_rational=1;
					}
	}
	if(is_rational!=1) /* not rational*/
		{
		 num_rt=power[0]-48;
	     for(j=0;j+1<strlen(power);j++)
						{
							num_rt=num_rt*10+(power[j+1]-48);/* ascii value of char 1 is 49*/
					}
		denum_rt=1;

	}





	printf("%g ",pows_f(base,num_rt,denum_rt));


	return 0;
}

double pows(double base,double n)
{


	if(base==0)
		return(0);
	else if(n==0)
		return(1);
	else if(n>=1)
		{
			return(base*pows(base,n-1));/*for positive powers*/

			}
	else if(n<=-1)
		{

			return(1/pows(base,-n));/*for negative powers*/
				        }
	else
		printf("error!");
		return(0);



}

double pows_f(double base,int num,int denum)/* num means numerator & denum means denomenator*/
{
	double pows_ed;/* variables to store  pows(ed) value*/
	pows_ed=pows(base,num);
	return root(pows_ed,denum);
}
Attachments
#include <stdio.h>

inline double _abs(double x) { return x < 0 ? -x : x; }
double _pow(double x, int e)
{
	double ret = 1;
	for (ret = 1; e; x *= x, e >>= 1)
		if ((e & 1)) ret *= x;
	return ret;
}

double root(double a, int n)                                     /*****nth_root_algoritm***************/
{                                                                /*   1. make an initial guess X0     */
	double x0, x1 = 1;                                       /*  2.XK+1=1/n((n-1)Xk + a/Xk^(n-1)) */
                                                                 /*  3.repeat step 2 until desired    */
	do {	x0 = x1;                                         /*    precision is met               */
		x1 = ((n - 1) * x1 + a / _pow(x1, (n - 1))) / n; /*************************************/
	} while (_abs(x0 - x1) > _abs(x1) * 1e-14);

	return x1;
}

//int main()
//{
//	double x = _pow(3.14159, 15);
//	printf("root(%g, 15) = %g\n", x, root(x, 15));
//	return 0;
//}
This article has been dead for over six months. Start a new discussion instead.