root functions?

Started by
7 comments, last by abd9e4790f 20 years, 6 months ago
I was sitting in math class and while the instructor was going over logarithmic functions, I was thinking about how you would go about making a root function (square root, cube root, etc.)? I''m sure there are some in the "math.h" file or "cmath.h" file (in C++) but has anyone created one on their own? "Do not flame people you don''t know in a public forum. Only amateurs do that. Professionals in the industry know they will run into each other over and over. The person you flame this year may the person you want to do business with next year. Don''t burn your bridges," (Diana Gruber, http://www.makegames.com/chapt6.html).
Advertisement
This forum is endlessly full of people screaming about how to make a wicked awesome tubular crazy fast square root function. Go back a few days, I think there just was one a day or two ago.
//Universal root function for whole numbers; returns the rootdouble root(double exp,int base){//Avoid computing known rootsif(base==0)return 0;else if(base==1)return 1;else if(base<0)return -1;//Compute unknown rootsint temp=base;  //Value of base; used in calculationfor(double i=0.0001;i<=base;i+=0.0001){temp=base;  //Restore valueif(int(pow(i,exp))==base)if(int(pow(int(i),exp)==base)) //Return single precision roots appropriatelyreturn int(i);else   //Return double-precision roots appropriatelyreturn i;elsecontinue;  //Try another number}return -1;  //Error}


it''s been a while since i''ve worked on it and it probably can be optomized.
Returning NaN or throwing a std::domain_error would be much more appropriate than returning -1

[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
pow(number, 1/exp);

exp = 2 for square root, 3 for cube, etc.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
The classical method of calculating sqrt() is to use Newton's method. There is a good concise explanation here.

For calculating the square root we use the equation x^2 - n, with the derivative 2x in Newton's method.

The following code is a working sqrt() implemenation using Newton's method:
#include <iostream>#include <limits>using namespace std;double mysqrt(double n) {	const double TOL = 1e-12;	const double N = 100;	if (n < 0) return std::numeric_limits<double>::quiet_NaN();	double guess = n / 2.0;	for (int i=0; i<N; i++) {		double f = guess * guess - n;		double df = 2 * guess;		if (fabs(f) < TOL) return guess;		double tmp = guess - f/df;		if (fabs(guess - tmp) < TOL) return guess;		guess = tmp;	}	return std::numeric_limits<double>::quiet_NaN();}int main() {	cout << mysqrt(0) << endl;}


Edit: Correction in algorithm for n = 0, fixed another bug with df being very close to zero.

[edited by - premandrake on October 16, 2003 1:06:42 PM]
I''m afraid that doesn''t work, Extrarius.
I am afraid it works.

pow(number, 1/(float) exp);

a small notice (1/3 is 0 in C )
be yourself.
It works when you put it into a function of its own as any sane person plus me would do:
inline double root(double num, double exp)
{
return pow(num, 1/exp);
}
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk

This topic is closed to new replies.

Advertisement