943,712 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Unsolved
  • Views: 29871
  • C++ RSS
You are currently viewing page 5 of this multi-page discussion thread; Jump to the first page
Sep 20th, 2009
0

Re: Square root program without sqrt or pwr

Credit needs to be given to you for your mathematical prowess though.

regards,
Reputation Points: 39
Solved Threads: 0
Junior Poster in Training
yonghc is offline Offline
55 posts
since Aug 2009
Sep 20th, 2009
0

Re: Square root program without sqrt or pwr

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.
CPP Syntax (Toggle Plain Text)
  1. //---------------------------------------------------------------------------
  2. void __fastcall TForm1::Button1Click(TObject *Sender)
  3. {
  4. double a, b, c, d, e(0.0000000001), count(0);
  5. a = atof(Edit1->Text.c_str());
  6. if(a < 0)
  7. {
  8. Label1->Caption = "Domain error!";
  9. return;
  10. }
  11. b = (1.0 + a)/2;
  12. c = (b - a/b)/2;
  13. d = fabs(c);
  14. while(d > e && count < 1000)
  15. {
  16. b -= c;
  17. c = (b - a/b)/2;
  18. d = fabs(c);
  19. ++count;
  20. }
  21. Label1->Caption = AnsiString(b) + " by algorithm";
  22. Label2->Caption = AnsiString(sqrt(a)) + " by sqrt() function";
  23. Label3->Caption = AnsiString(count) + " itterations";
  24. }
  25. //---------------------------------------------------------------------------
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.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
Foamgum is offline Offline
9 posts
since Sep 2009
Sep 20th, 2009
0

Re: Square root program without sqrt or pwr

Click to Expand / Collapse  Quote originally posted by Foamgum ...
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.
CPP Syntax (Toggle Plain Text)
  1. //---------------------------------------------------------------------------
  2. void __fastcall TForm1::Button1Click(TObject *Sender)
  3. {
  4. double a, b, c, d, e(0.0000000001), count(0);
  5. a = atof(Edit1->Text.c_str());
  6. if(a < 0)
  7. {
  8. Label1->Caption = "Domain error!";
  9. return;
  10. }
  11. b = (1.0 + a)/2;
  12. c = (b - a/b)/2;
  13. d = fabs(c);
  14. while(d > e && count < 1000)
  15. {
  16. b -= c;
  17. c = (b - a/b)/2;
  18. d = fabs(c);
  19. ++count;
  20. }
  21. Label1->Caption = AnsiString(b) + " by algorithm";
  22. Label2->Caption = AnsiString(sqrt(a)) + " by sqrt() function";
  23. Label3->Caption = AnsiString(count) + " itterations";
  24. }
  25. //---------------------------------------------------------------------------
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.
Please correct me if I am wrong.

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,
Reputation Points: 39
Solved Threads: 0
Junior Poster in Training
yonghc is offline Offline
55 posts
since Aug 2009
Sep 20th, 2009
0

Re: Square root program without sqrt or pwr

There is always brute force :

C++ Syntax (Toggle Plain Text)
  1. float SquareRootOf(int num)
  2. {
  3. int i = 0;
  4. //Check for perfect square root
  5. for(i = 0; ; i++)
  6. {
  7. if(i * i > num) break;
  8. else if(i * i == num) return float(i);
  9. }
  10.  
  11. i-=2;
  12. float j = i;
  13. float precision = 0.00001f;
  14. while(j * j < num - precision )
  15. j+=precision;
  16.  
  17. return j;
  18. }
Last edited by firstPerson; Sep 20th, 2009 at 2:37 pm.
Reputation Points: 840
Solved Threads: 594
Senior Poster
firstPerson is offline Offline
3,862 posts
since Dec 2008
Sep 20th, 2009
0

Re: Square root program without sqrt or pwr

ooh, sqrt(4)=4^(1/2)=2
might help

where sqrt = Square root
^ = to the power of

oh, hang on...
no to the pwr of...

well if 4x4x4 = 4^3 = 64
and then 4^1/2 = .... urrgh - im screwed.
Last edited by maxicube; Sep 20th, 2009 at 2:42 pm.
Reputation Points: 10
Solved Threads: 0
Light Poster
maxicube is offline Offline
32 posts
since Nov 2008
Sep 20th, 2009
0

Re: Square root program without sqrt or pwr

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.

C++ Syntax (Toggle Plain Text)
  1. float sqrt (float x)
  2. {
  3. float xhalf = 0.5f*x;
  4. int i = *(int*)&x;
  5. i = 0x5f3759df - (i>>1);
  6. x = *(float*)&i;
  7. return 1/(x*(1.5f - xhalf*x*x));
  8. }

Or to increase of precision:

C++ Syntax (Toggle Plain Text)
  1. float sqrt (float x)
  2. {
  3. float xhalf = 0.5f*x;
  4. int i = *(int*)&x;
  5. i = 0x5f3759df - (i>>1);
  6. x = *(float*)&i;
  7. for(int k=0; k<5; k++)
  8. x*=(1.5f - xhalf*x*x);
  9. return 1.0f/x;
  10. }
Last edited by invisal; Sep 20th, 2009 at 2:44 pm.
Reputation Points: 350
Solved Threads: 63
Posting Pro
invisal is offline Offline
562 posts
since Mar 2005
Sep 20th, 2009
2

Re: Square root program without sqrt or pwr

>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?
Administrator
Reputation Points: 6442
Solved Threads: 1393
Bad Cop
Narue is offline Offline
11,807 posts
since Sep 2004
Sep 20th, 2009
0

Re: Square root program without sqrt or pwr

here is a simple brute force way of doing the nth root of a number.
c++ Syntax (Toggle Plain Text)
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. double NthRoot(double, int);
  5.  
  6. double RaisedTo(double, int);
  7.  
  8. double NthRoot(double number, int nthRoot )
  9. {
  10. bool done = false;
  11. unsigned short int digits = 0;
  12. double temp = number / 2;
  13. double sqrt = 0;
  14. double plusplus = 1;
  15. if (number == 1)
  16. return 1;
  17. for (;;)
  18. {
  19. if (digits > 0)
  20. plusplus /= 10.0;
  21. if (digits == 12)
  22. return sqrt;
  23. for ( double i = sqrt; i <= (temp + 1); i += plusplus)
  24. {
  25. if (RaisedTo(i, nthRoot) > number)
  26. {
  27. sqrt = i - plusplus;
  28. digits++;
  29. break;
  30. }
  31. }
  32. }
  33. }
  34.  
  35. double RaisedTo(double base, int power)
  36. {
  37. double temp;
  38. for (int i = 1; i < power; i++)
  39. {
  40. base *= temp;
  41. }
  42. return base;
  43. }
  44.  
  45. int main()
  46. {
  47. double number = 0;
  48. double answer;
  49. int root;
  50. cout << "Please enter a number to find the nth root: ";
  51. cin >> number;
  52. cout << "Please enter the root you wish to find: ";
  53. cin >> root;
  54. answer = NthRoot(number, root);
  55. cout << "The " << root << "th root is: " << answer << endl;
  56. cin.get();
  57. cin.get();
  58. return 0;
  59. }
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
Reputation Points: 215
Solved Threads: 186
Veteran Poster
NathanOliver is offline Offline
1,066 posts
since Apr 2009
Sep 20th, 2009
0

Re: Square root program without sqrt or pwr

<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.
cpp Syntax (Toggle Plain Text)
  1. //---------------------------------------------------------------------------
  2. void __fastcall TForm1::Button1Click(TObject *Sender)
  3. {
  4. double a, b, c, d, e(0.0000000001), f, count(0);
  5. a = atof(Edit1->Text.c_str());
  6. if(a < 0)
  7. {
  8. Label1->Caption = "Domain error!";
  9. return;
  10. }
  11. while(e > a) // For very small values the criterion for stopping needs to be smaller.
  12. e /= 10;
  13. b = (1.0 + a)/2; // First estimate of square root of a.
  14. c = (b - a/b)/2; // Correction to give a better estimate.
  15. while(c > e && count < 1000)
  16. {
  17. f = b; // For very small and very large values we will see
  18. b -= c; // if the correction has any effect.
  19. c = (b - a/b)/2; // A revised correction.
  20. if(f == b) // Applying the correction made no difference to our answer.
  21. break;
  22. ++count; // A counter to measure the effectiveness of our algorithm.
  23. }
  24. Label1->Caption = AnsiString(b) + " by algorithm"; // Our answer.
  25. Label2->Caption = AnsiString(sqrt(a)) + " by sqrt() function"; // The true answer for comparison.
  26. Label3->Caption = AnsiString(count) + " iterations"; // Tells us how much effort it took.
  27. }
  28. //---------------------------------------------------------------------------
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
Reputation Points: 10
Solved Threads: 0
Newbie Poster
Foamgum is offline Offline
9 posts
since Sep 2009
Sep 20th, 2009
0

Re: Square root program without sqrt or pwr

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.
cpp Syntax (Toggle Plain Text)
  1. //---------------------------------------------------------------------------
  2. void __fastcall TForm1::Button1Click(TObject *Sender)
  3. {
  4. double a, b;
  5. int count(0);
  6. a = atof(Edit1->Text.c_str());
  7. b = MySQRT(a, &count);
  8. if(a < 0)
  9. {
  10. Label1->Caption = "Domain error!";
  11. return;
  12. }
  13. Label1->Caption = AnsiString(b) + " by algorithm"; // Our answer.
  14. Label2->Caption = AnsiString(sqrt(a)) + " by sqrt() function"; // The true answer for comparison.
  15. Label3->Caption = AnsiString(count) + " iterations"; // Tells us how much effort it took.
  16. }
  17. //---------------------------------------------------------------------------
  18. double __fastcall TForm1::MySQRT(double number, int *iterations)
  19. {
  20. double b, c, e(1e-12), f;
  21. if(number < 0)
  22. return -1;
  23. while(e > number) // For very small values the criterion for stopping needs to be smaller.
  24. e /= 10;
  25. b = (1.0 + number)/2; // First estimate of square root of number.
  26. c = (b - number/b)/2; // Correction to give a better estimate.
  27. while(c > e && (*iterations) < 1000)
  28. {
  29. f = b; // For very small and very large values we will see
  30. b -= c; // if the correction has any effect.
  31. if(f == b) // Applying the correction made no difference to our answer.
  32. return b;
  33. c = (b - number/b)/2; // A revised correction.
  34. ++(*iterations); // A counter to measure the effectiveness of our algorithm.
  35. }
  36. return b;
  37. }
  38. //---------------------------------------------------------------------------
Regards
Foamgum
Reputation Points: 10
Solved Threads: 0
Newbie Poster
Foamgum is offline Offline
9 posts
since Sep 2009

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: Nested If and Looping
Next Thread in C++ Forum Timeline: can anyone help me with my c++ homework?





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC