Square root extractor

caut_baia 0 Tallied Votes 400 Views Share

Hi.Someone asked a day or two ago for a way to extract the square root of a number without using the std::sqrt function so i thought about writing my own.Here it is and please feel free to criticize.

#include <iostream>
#include <deque>
#include <string>
#include <limits>
#include <sstream>
#include <iomanip>

/* Obtaining square root using the decimimal method */

class square_root  {
        double result,tmp,rmndr;                                    																						
	long input;
	double decim;              //Will contain the number of trailing decimimals.
	std::deque<double> tokens; //Will contain the tokenized 'input' value.
	square_root ();           

	/* Aproximates the biggest number 'n' given as input 'a' and 'x' such that ( y=(a*20)+n | x - (y*n) < y )  */
	double aprox (double a,double x)  {    
		double ret=1;
		a*=20;
		while ((a+ret)*ret <= x)  {
			ret++;
		 }
		ret--;
		return ret;
	 }

        void sqt (double num,bool point=0)  {        // 3  45  34. 00    | 185.8
		rmndr*=100;                          // 3-               |________________________________________
		rmndr+=num;                          // 1=               | 1*1=1 < 3                      => 1
		tmp=aprox (result,rmndr);            //   245-           | (((1*2)*10)+8)*8=224 < 245     => 8
		rmndr-=((result*20)+tmp)*tmp;        //   224            | 
		result*=10;                          //      2134-       | (((18*2)*10)+5)*5=1825 < 2134  => 5
		result+=tmp;                         //      1825        |
		if (point==1)  {                     //          33900   | (((185*2)*10)+8)*8=29664 < 33900 => 0.8
		        decim*=10;
		 }			
	 }
	
	/* Tokenizes a number by grouping it's digits in pairs of two from back to front
	 * and stores them in 'tokens'.
	 *		ex: input=3453545;  
	 * Now 'tokens' will contain four objects (45,35,45,3) 
	 */

	void tokenize (long inp)  {
		const long step=100;
		for (long x=step,y=1;x <= inp*step;x*=step,y*=step)  {
			double tok=((inp%x - inp%y) / y);
			tokens.push_front (tok);
		 }
	 }

public:
	explicit square_root (long input_) : input(input_), result(0), rmndr(0), tmp(0), decim(1)  {
		if (input <= std::numeric_limits<long>().max())  {
			tokenize (input);
			for (std::deque<double>::iterator i=tokens.begin();i!=tokens.end();++i)  {	
				sqt (*i);
			 }
                         //calling sqt with 'point' set starts counting trailing decimals
			for (int x=0;x<square_root::precision;x++) sqt(0,1);
			/* Dividing to the apropriate value */
			result/=decim;
		 }		
	 }
        ~square_root () {}

	static const int precision=25;
	operator double () const  {
		return result;
	 }
 };

int main (int argc,char* argv[])  {	
	long n;
	std::stringstream (argv[1]) >> n;
	std::cout << "\n\n\n" << std::fixed << std::setprecision(square_root::precision) << square_root (n) << "\n\n\n\n";
 }
maninaction -9 Junior Poster in Training

Great work . Thanks for sharing

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.