| | |
Square root program without sqrt or pwr
Please support our C++ advertiser: Intel Parallel Studio Home
![]() |
•
•
Join Date: Sep 2009
Posts: 7
Reputation:
Solved Threads: 0
I noticed this thread and couldn't help wondering why noone used the rather simple algorithm used below.
I program in C++Builder so you may need to adapt the code if you want to use it elsewhere. I have a form with an Edit box for input, a button to start the calculation and three labels to show the output.
Almost any positive number input gives a valid output.
You'll find the number of itterations is quite small and the comparison with sqrt() is very good. You could make e smaller to get a better result.
I program in C++Builder so you may need to adapt the code if you want to use it elsewhere. I have a form with an Edit box for input, a button to start the calculation and three labels to show the output.
Almost any positive number input gives a valid output.
CPP Syntax (Toggle Plain Text)
//--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { double a, b, c, d, e(0.0000000001), count(0); a = atof(Edit1->Text.c_str()); if(a < 0) { Label1->Caption = "Domain error!"; return; } b = (1.0 + a)/2; c = (b - a/b)/2; d = fabs(c); while(d > e && count < 1000) { b -= c; c = (b - a/b)/2; d = fabs(c); ++count; } Label1->Caption = AnsiString(b) + " by algorithm"; Label2->Caption = AnsiString(sqrt(a)) + " by sqrt() function"; Label3->Caption = AnsiString(count) + " itterations"; } //---------------------------------------------------------------------------
•
•
Join Date: Aug 2009
Posts: 55
Reputation:
Solved Threads: 0
•
•
•
•
I noticed this thread and couldn't help wondering why noone used the rather simple algorithm used below.
I program in C++Builder so you may need to adapt the code if you want to use it elsewhere. I have a form with an Edit box for input, a button to start the calculation and three labels to show the output.
Almost any positive number input gives a valid output.
You'll find the number of itterations is quite small and the comparison with sqrt() is very good. You could make e smaller to get a better result.CPP Syntax (Toggle Plain Text)
//--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { double a, b, c, d, e(0.0000000001), count(0); a = atof(Edit1->Text.c_str()); if(a < 0) { Label1->Caption = "Domain error!"; return; } b = (1.0 + a)/2; c = (b - a/b)/2; d = fabs(c); while(d > e && count < 1000) { b -= c; c = (b - a/b)/2; d = fabs(c); ++count; } Label1->Caption = AnsiString(b) + " by algorithm"; Label2->Caption = AnsiString(sqrt(a)) + " by sqrt() function"; Label3->Caption = AnsiString(count) + " itterations"; } //---------------------------------------------------------------------------
I would like to hazard a guess. You could be using MS Visual C++. I believe that your codes rely on some other external files, such as Win API, dynamic link library files, etc., and you make use of them to effect GUI, like 3-d buttons, etc. without the need to code them. I know that even simple MS Foxprow executable program can not run without huge foxprow.esl library files, exceeding 1.2 MB.
What I have written was based on the context of a stand-alone C++ program compiled using non-commercial/ non-proprietary C++ compiler, such as CODE::BLOCK, Dev-C++, and Borland C++; and users can use the codes without other overheads, for which they have to pay a price. The executable C++ file can be very small, like 16K. I think users, perhaps including the OP, who use such compilers, -- which I use myself -- can not use your much simplified codes.
I think the freedom of choice of compilers is important. We need not be dependent on a proprietary C++. owned by a ruthless behemoth bent on monopolizing PC based software. We need to be able to breathe freely.
Regards,
There is always brute force :
C++ Syntax (Toggle Plain Text)
float SquareRootOf(int num) { int i = 0; //Check for perfect square root for(i = 0; ; i++) { if(i * i > num) break; else if(i * i == num) return float(i); } i-=2; float j = i; float precision = 0.00001f; while(j * j < num - precision ) j+=precision; return j; }
Last edited by firstPerson; Sep 20th, 2009 at 2:37 pm.
I give up! 1) What word becomes shorter if you add a letter to it? [ Solved by : niek_e ] 2) What does this sequence equal to : (.5u - .5a)(.5u-.5b)(.5u-.5c) ... 3) What is the 123456789 prime numer? Ask4Answer
May I add another algorithm that does not use log and power function; yet still run relatively fast. This function makes use of fast inverse square root algorithm which works only with 32-bits unsigned float number as input.
Or to increase of precision:
C++ Syntax (Toggle Plain Text)
float sqrt (float x) { float xhalf = 0.5f*x; int i = *(int*)&x; i = 0x5f3759df - (i>>1); x = *(float*)&i; return 1/(x*(1.5f - xhalf*x*x)); }
Or to increase of precision:
C++ Syntax (Toggle Plain Text)
float sqrt (float x) { float xhalf = 0.5f*x; int i = *(int*)&x; i = 0x5f3759df - (i>>1); x = *(float*)&i; for(int k=0; k<5; k++) x*=(1.5f - xhalf*x*x); return 1.0f/x; }
Last edited by invisal; Sep 20th, 2009 at 2:44 pm.
Yesterday is a history, tomorrow is a mystery, today is a gift.
Behind every smile is a tear.
Visal .In
Behind every smile is a tear.
Visal .In
>Please correct me if I am wrong.
You're wrong, and in a most amusing way.
>I think the freedom of choice of compilers is important. We need not
>be dependent on a proprietary C++. owned by a ruthless behemoth
>bent on monopolizing PC based software. We need to be able to breathe freely.
You think freedom of choice is important, but only when those choices conform to your personal biases. Yep, that makes perfect sense.
Unfortunately, this type of religious fanatic non-logic is also quite typical of Microsoft haters.
>What I have written was based on the context of a stand-alone
>C++ program compiled using non-commercial/ non-proprietary
>C++ compiler, such as CODE::BLOCK, Dev-C++, and Borland C++
Borland, huh?
You're wrong, and in a most amusing way.
>I think the freedom of choice of compilers is important. We need not
>be dependent on a proprietary C++. owned by a ruthless behemoth
>bent on monopolizing PC based software. We need to be able to breathe freely.
You think freedom of choice is important, but only when those choices conform to your personal biases. Yep, that makes perfect sense.
>What I have written was based on the context of a stand-alone
>C++ program compiled using non-commercial/ non-proprietary
>C++ compiler, such as CODE::BLOCK, Dev-C++, and Borland C++
Borland, huh?
I'm here to prove you wrong.
here is a simple brute force way of doing the nth root of a number.
i haven't attempted to clock it but does return pretty quick with most numbers. also on line 20 is where you can set the precision you desire. i used 12 for a default
c++ Syntax (Toggle Plain Text)
#include <iostream> using namespace std; double NthRoot(double, int); double RaisedTo(double, int); double NthRoot(double number, int nthRoot ) { bool done = false; unsigned short int digits = 0; double temp = number / 2; double sqrt = 0; double plusplus = 1; if (number == 1) return 1; for (;;) { if (digits > 0) plusplus /= 10.0; if (digits == 12) return sqrt; for ( double i = sqrt; i <= (temp + 1); i += plusplus) { if (RaisedTo(i, nthRoot) > number) { sqrt = i - plusplus; digits++; break; } } } } double RaisedTo(double base, int power) { double temp; for (int i = 1; i < power; i++) { base *= temp; } return base; } int main() { double number = 0; double answer; int root; cout << "Please enter a number to find the nth root: "; cin >> number; cout << "Please enter the root you wish to find: "; cin >> root; answer = NthRoot(number, root); cout << "The " << root << "th root is: " << answer << endl; cin.get(); cin.get(); return 0; }
if you write
If your thread is solved please mark it as solved
using namespace std; you do not need to write std::something in your program.If your thread is solved please mark it as solved
•
•
Join Date: Sep 2009
Posts: 7
Reputation:
Solved Threads: 0
<Please correct me if I'm wrong.
A couple of points here. I mentioned in the original post that I was using C++Builder, originally a Borland product, then CodeGear and now Embarcadero. I left the code as I used it thinking that one idea behind these posts was to point people in the right direction rather than give complete solutions to problems. It is easy to convert the pertinant code to any C++ platform.
If you wish I can rewrite the code using an external function, but it is easy enough for you to do that yourself.
There was one problem with my code. It works fine for most numbers but not very small or very large numbers. Try 5e-150 for example. The following modified code works very well for all double precision numbers. The comments in the code explain some other improvements. Also there was no need for the fabs() function as c is always positive.
If you are having trouble addapting this code I can rewrite it as a function that can be used on any C++ platform.
Cheers
Foamgum
A couple of points here. I mentioned in the original post that I was using C++Builder, originally a Borland product, then CodeGear and now Embarcadero. I left the code as I used it thinking that one idea behind these posts was to point people in the right direction rather than give complete solutions to problems. It is easy to convert the pertinant code to any C++ platform.
If you wish I can rewrite the code using an external function, but it is easy enough for you to do that yourself.
There was one problem with my code. It works fine for most numbers but not very small or very large numbers. Try 5e-150 for example. The following modified code works very well for all double precision numbers. The comments in the code explain some other improvements. Also there was no need for the fabs() function as c is always positive.
cpp Syntax (Toggle Plain Text)
//--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { double a, b, c, d, e(0.0000000001), f, count(0); a = atof(Edit1->Text.c_str()); if(a < 0) { Label1->Caption = "Domain error!"; return; } while(e > a) // For very small values the criterion for stopping needs to be smaller. e /= 10; b = (1.0 + a)/2; // First estimate of square root of a. c = (b - a/b)/2; // Correction to give a better estimate. while(c > e && count < 1000) { f = b; // For very small and very large values we will see b -= c; // if the correction has any effect. c = (b - a/b)/2; // A revised correction. if(f == b) // Applying the correction made no difference to our answer. break; ++count; // A counter to measure the effectiveness of our algorithm. } Label1->Caption = AnsiString(b) + " by algorithm"; // Our answer. Label2->Caption = AnsiString(sqrt(a)) + " by sqrt() function"; // The true answer for comparison. Label3->Caption = AnsiString(count) + " iterations"; // Tells us how much effort it took. } //---------------------------------------------------------------------------
Cheers
Foamgum
•
•
Join Date: Sep 2009
Posts: 7
Reputation:
Solved Threads: 0
In the spirit of C++ coding I've rewritten this with an external function that could be put into a library. When you were confident that you didn't need to see how many iterations there were you could remove that part of the function.
Regards
Foamgum
cpp Syntax (Toggle Plain Text)
//--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { double a, b; int count(0); a = atof(Edit1->Text.c_str()); b = MySQRT(a, &count); if(a < 0) { Label1->Caption = "Domain error!"; return; } Label1->Caption = AnsiString(b) + " by algorithm"; // Our answer. Label2->Caption = AnsiString(sqrt(a)) + " by sqrt() function"; // The true answer for comparison. Label3->Caption = AnsiString(count) + " iterations"; // Tells us how much effort it took. } //--------------------------------------------------------------------------- double __fastcall TForm1::MySQRT(double number, int *iterations) { double b, c, e(1e-12), f; if(number < 0) return -1; while(e > number) // For very small values the criterion for stopping needs to be smaller. e /= 10; b = (1.0 + number)/2; // First estimate of square root of number. c = (b - number/b)/2; // Correction to give a better estimate. while(c > e && (*iterations) < 1000) { f = b; // For very small and very large values we will see b -= c; // if the correction has any effect. if(f == b) // Applying the correction made no difference to our answer. return b; c = (b - number/b)/2; // A revised correction. ++(*iterations); // A counter to measure the effectiveness of our algorithm. } return b; } //---------------------------------------------------------------------------
Foamgum
![]() |
| Thread Tools | Search this Thread |
api array arrays based beginner binary bitmap c++ c/c++ calculator char char* class code coding compile compiler console conversion count data database delete deploy developer dll download dynamiccharacterarray email encryption error file forms fstream function functions game getline givemetehcodez graph gui homeworkhelp homeworkhelper iamthwee ifstream input int integer java lib linker list loop looping loops map math matrix memory multiple news node number numbertoword output parameter pointer problem program programming project proxy python random read recursion recursive reference rpg sorting string strings struct temperature template text text-file tree url variable vector video visual visualstudio win32 windows winsock word wordfrequency wxwidgets






