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.
Square root extractor
#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
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.