December 9th, 2013, 01:25 PM

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 < (x0.00001))
{
y = y + adder;
if (y*y > (x0.00001))
{
adder = adder/2;
break;
}
}
if(y*y > (x+0.00001))
{
y = yadder;
if(y*y < (x+0.00001))
{
adder = adder/2;
break;
}
}
if(y*y > (x0.00001) && y*y < (x+0.00001)) break;
}
//**************************
}
return y;
}
December 9th, 2013, 02:43 PM

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 01:28 PM.
[code]
Code tags[/code] are essential for python code and Makefiles!
December 10th, 2013, 01:03 PM

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 < (xcst)  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;
}
December 10th, 2013, 03:10 PM

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 25e12.
Code:
#if 0
$ a=./c && make k $a && $a 25 2.5e11
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.5e11 2.500e11 1.000e+00 5.000e06
#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 < (xcst)  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((yz)/z),fabs(yz));
}
return 0;
}
[code]
Code tags[/code] are essential for python code and Makefiles!