0

Hello, I've written a C++ class which 'estimates' the roots of a given number ...
It was called 'sqr' because it was first intended to estimate square roots only, but later on I made some little changes to my code which made it possible to estimate every root ...
So, some method's/variable's names are already deprecated, sorry for that ...

This is a sample program which demonstrates the use of the sqr class:

#include <iostream>
#include <cstdlib>
#include "sqr" /* Header file where the declarations of the sqr class reside in */

using namespace std;

int main()
{
    double tmp;
    sqr wortel_object(0);
    system("CLS");
    cout << "*** SQR-OBJECT DEMO ***" << endl;
    cout << endl << endl << "Type n-root: ";
    cin >> tmp;
    wortel_object.setnsqr(static_cast <int> (tmp));
    cout << endl << "Type a number: ";
    cin >> tmp;
    wortel_object.setsqr(tmp);
    cout << endl << "Type the desired precision: ";
    cin >> tmp;
    wortel_object.setprecision(static_cast <int> (tmp));
    cout.precision(10);
    cout << endl << "The (estimated) " << wortel_object.getnsqr() << "th root of " << wortel_object.getsqr() << " is: " << wortel_object.estimate() << endl;
    cout << endl << "The precision was: " << wortel_object.getprecision() << endl;
    cout << endl << "The calculation time was: " << wortel_object.getcalctime() << " seconds ..." << endl << endl;
    return 0;
}

P.S.: I put much effort in translating all the comments I made from Dutch to English, so sorry if my English is bad ...

/**************************************************************************************************************************
* SQR CLASS by: 'Mathias Van Malderen'
* Copyright (c) 2009 Mathias Van Malderen
*
* Disclaimer:
* ~~~~~~~~~~~
*
* Free to use for everyone!
* It is not allowed to sell this source code !
*
* Description:
* ~~~~~~~~~~~~
*
* 1) You create an object from the class 'sqr';
* 2) You put the value of which you want to calculate the n-root in the object using the method 'setsqr(<double>)';
* 3) (Optional) You set the 'precision' and 'n-root' (If you don't do this, the program will automatically estimate the square root with 'precision' = 1000 if you call the 'estimate()' method);
* 4) You call the method 'estimate()' to estimate the desired n-root ...
* 5) Enjoy !!
*
*
* Remarks:
* ~~~~~~~~
*
* !!: This class only returns valid results for values higher than zero ...
*
* TODO:
* ~~~~~
*
* <nothing>
*
***************************************************************************************************************************/

#include <iostream>
using namespace std;

class sqr
{
public:
    sqr(double asqr_in);
	void init(double asqr_in);
	void setsqr(double asqr_in);
	double estimate();
	void setprecision(long aprecision);
	void setnsqr(int ansqr);
	long getprecision();
	int getnsqr();
	double getsqr();
	int getcalctime();
private:
    long t_begin, t_end;
    double sqr_in, s, l, h, tmp;
    long precision;
    int nsqr;
    double apow(float x, int y);
};

sqr::sqr(double asqr_in)
{
	/* Constructor */
    init(asqr_in);
}
void sqr::setprecision(long aprecision){precision = aprecision;} /* Set the precision, the higher, the more precise the estimation is */
long sqr::getprecision(){return precision;} /* Returns the set precision */
int sqr::getnsqr(){return nsqr;} /* Returns the root which you are estimating */
double sqr::getsqr(){return sqr_in;} /* Returns the number of which you want to estimate the root */
int sqr::getcalctime(){return (t_end - t_begin);} /* Returns the total calculation time (in whole seconds) */
void sqr::init(double asqr_in)
{
	/* Public method to make it possible for the user to 'reinitialize' the object */
    sqr_in = asqr_in;
    precision = 1000;
    nsqr = 2;
    s = 0;
    l = 0;
    h = 0;
    tmp = 0;
}
void sqr::setnsqr(int ansqr)
{
	/* Set the root you want to estimate */
	if(ansqr >= 2)
	{
		nsqr = ansqr;
	}
}
void sqr::setsqr(double asqr_in)
{
	/* Set the number where you want to estimate the n-root of */
	if(!(asqr_in < 0))
	{
		sqr_in = asqr_in;
	}
}
double sqr::apow(float x, int y)
{
	/* This is a private method of the class, it's only a dependency */
	long double result = 1;
	if (y == 0)
		return result;
			
	if (y < 0)
	{
		y = -y;
		for (int i = 0; i < y; i++)
			result = result * x;
		return 1/result;
	}

	for (int i = 0; i < y; i++)
		result = result * x;
			
	return result;
}
double sqr::estimate()
{
	/* Estimate the root of a given number */
	t_begin = time(0);
	/****** BEGIN ALGORITHM ******/
	tmp = sqr_in;

	if(sqr_in < 1 && sqr_in > 0)
	{
		/* The root must be in between 0 (= zero) and 1 (= one) */
		l = 0;
		h = 1;
		s = 0.5;
	} else {
		/* Calculate two numbers 'l' (= lowest) and 'h' (= highest) where the root must be in between */
		do
		{
			tmp = tmp / 2;
		}
		while (apow(tmp, nsqr) > sqr_in);
		l = tmp;
		h = tmp*2;
	}

	/* Start estimating the desired root */
	for (int i = 0; i < precision; i++)
	{
		/* Calculate the average of 'l' and 'h' and store the result in variable 's' */
		s = (l+h)/2;
		tmp = apow(s, nsqr);
		if (tmp > sqr_in)
		{
			/* The estimated root is too high */
			h = s;
		}
		else if (tmp < sqr_in)
		{
			/* The estimated root is too low */
			l = s;
		}
		else
		{
			/* We have found the 'exact' root */
			/* Speedbooster */
			break;
		}
	}
	/****** END ALGORITHM ******/
	t_end = time(0);
	return s;
}
1
Contributor
1
Reply
2
Views
7 Years
Discussion Span
Last Post by mvmalderen
0

You should replace the 'apow' function by the updated one:

double apow(const double &x, int y)
{
    double result = 1;
    if(y < 0)
	return apow(1/x, -y);
    for(int i = y; i > 0; i--)
	result *= x;
    return result;
}
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.