Thread: C++ square root

    #1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2013
    Posts
    3
    Rep Power
    0

    C++ square root


    Hello :)
    i have written a function that gives me the square root of a number. Yes i know there is already a function in <cmath> that gives square roots but i thought it would be pretty challenging (and therefore fun) to try writing one on my own. I wrote my code while i was in school, listening to my Irish teacher ramble on and on about useless ****, so it's probably not the best possible way of finding the square root of a number.

    so here's where you come in ;)
    i'd love if i could get some advice on my function and maybe different ways of achieving the same thing but with less code. thank you :)

    Code:
    double msqrt(double x)
    {
    	double adder=1;
    	double y = x;
    
    
    	for(int a=0; ; a++)
    	{
    		if(y*y > x) y = y/2;
    		if(y*y <= x) break;
    	}
    //**************************
    
    	while (y*y < (x - 0.00001) || y*y > (x + 0.00001))
    	{
    		for (int a=0; ; a++)
    		{
    			if(y*y < (x-0.00001))
    			{
    				y = y + adder;
    				if (y*y > (x-0.00001))
    				{
    					adder = adder/2;
    					break;
    				}
    			}
    
    			if(y*y > (x+0.00001))
    			{
    				y = y-adder;
    				if(y*y < (x+0.00001))
    				{
    					adder = adder/2;
    					break;
    				}
    			}
    
    
    			if(y*y > (x-0.00001) && y*y < (x+0.00001)) break;
    		}
    //**************************
    	}
    
    
    	return y;
    }
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,711
    Rep Power
    480
    Looping constructs of c:


    for(;;) /* means repeat forever */

    do statement; while (condition);

    while (condition) statement;


    Your counter of `a' gives you the opportunity to terminate the loop after some number of iterations.



    Newton's method is supreme for finding zeros of functions. You'd approximate the derivative since the derivative of square root involves that which you're trying to compute.



    You might also include a relative error termination for your loops. Otherwise you'll needlessly restrict the domain of msqrt.


    You could compute the power series for log(x) expanded about 1 (I suppose they usually call this ln(1+x)), divide by 2, the compute exp(x).
    Last edited by b49P23TIvg; December 10th, 2013 at 12:28 PM.
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2013
    Posts
    3
    Rep Power
    0
    ahh i see.. is this what you meant?
    Code:
    double msqrt(double x)
    {
    	double adder = 1;
    	double y = x;
    	double cst = 0.00001;
    	while (y*y > x) y /= 2;
    
    	while (y*y < (x-cst) || y*y > (x+cst))
    	{
    		if(y*y < x)
    		{
    			y += adder;
    			if(y*y > x)adder /= 2;
    		}
    
    		if(y*y > x)
    		{
    			y -= adder;
    			if(y*y < x)adder /= 2;
    		}
    	}
    		return y;
    }
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,711
    Rep Power
    480

    Relative error.


    In part. Your loops were, I think, workable. The numerical test is the real trouble. Your program finds the square root of 25 but not the square root of 25e-12.
    Code:
    #if 0
      $ a=./c && make -k $a && $a 25 2.5e-11
      cc -Wall -g c.c -lm -o c
                  x     msqrt(x)  relative error  absolute error
                 25    5.000e+00       0.000e+00       0.000e+00
            2.5e-11    2.500e-11       1.000e+00       5.000e-06
    #endif
    
    #include<stdlib.h>
    #include<stdio.h>
    #include<math.h>
    
    double msqrt(double x) {
      double adder = 1;
      double y = x;
      double cst = 0.00001;
      while (y*y > x) y /= 2;
      while (y*y < (x-cst) || y*y > (x+cst)) {
        if(y*y < x) {
          y += adder;
          if(y*y > x)adder /= 2;
        }
        if(y*y > x) {
          y -= adder;
          if(y*y < x)adder /= 2;
        }
      }
      return y;
    }
    
    int main(int ac,char*av[]) {
      double x, y, z;
      printf("%15s %12s %15s %15s\n","    x",  "   msqrt(x)","relative error","absolute error");
      while (NULL != *++av) {
        x = atof(*av);
        y = msqrt(x);
        z = sqrt(x);
        printf("%15s %12.3e %15.3e %15.3e\n",*av,y,fabs((y-z)/z),fabs(y-z));
      }
      return 0;
    }
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo