0
#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*/

			}



}
3
Contributors
23
Replies
25
Views
5 Years
Discussion Span
Last Post by D33wakar
0

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)?

0

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

0

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 by pyTony: n/a

0

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.

0

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.

0

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

0

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.

0

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.

0

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.

0

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 by pyTony: n/a

0

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?

0

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;
//}
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).

0

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).

0

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).

0

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.

0

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 topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.