# How to make sqrt function in C?

## Question:

I am trying to do a `sqrt()` function; the function i got is very slow. How can I make it faster?

``````#include <stdio.h>
#include <math.h>
double root(double x);

int main(){
printf("%f",root(3));
printf("\n%f",sqrt(3));
return 0;
}

double root(double x){
long double a[9];
long double b[9]={1.0,0.1,0.01,0.001,0.0001,0.00001,0.000001};

int i=0;
for(i=0;i<9;i++){
a[i]=0.0;
}

i=-1;
while(a[i]*a[i]!=x){
if(i==8)
i=-1;
i++;
a[i]+=b[i];
if(a[6]*a[6]>x)
return a[6];
else if(a[5]*a[5]==x)
return a[5];
else if(a[4]*a[4]==x)
return a[4];
}
return a[i];
}

``````

I made this function on the basis that if you multiply all the numbers, you will be able to find the square root.

Summary of the original method

The method consists of bringing several counters in parallel in `a` . The counter `a[0]` advances by 1 by 1, while `a[1]` advances by 0.1 by 0.1, and so on.

In each iteration each counter is advanced and then it checks if the counter `a[4]` a `a[6]` already have the desired root, returning it.

In total, more than 1.7 million iterations were made to calculate the root of 3.

New method

I collect the essence of the method: I will start by adding 1 to the tentative root until its square exceeds the received parameter. I will discount 1 and then I will repeat the operation advancing from 0.1 to 0.1 until the square exceeds the parameter. I will subtract 0.1 and then continue with 0.01 and so on.

The calculation stops when the root is found exactly or until the factor to be added is too small, and therefore does not produce a change in the root:

``````double root(double x) {
long double b[9] = {1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001};

double raiz = 0;
for (int i = 0; i < 9; i++) {
double ant = -1;
while ((raiz * raiz) <= x && raiz != ant) {
ant = raiz;
raiz += b[i];
}
raiz -= b[i];
};
return raiz;
}
``````

Demo

``````int main() {
for (int i=1; i < 20; i++) {
printf("%d %f\n", i, root(i));
}
return 0;
}
``````

produce:

``````1 1.000000
2 1.414213
3 1.732050
4 2.000000
5 2.236067
6 2.449489
7 2.645751
8 2.828427
9 3.000000
10 3.162277
11 3.316624
12 3.464101
13 3.605551
14 3.741657
15 3.872983
16 4.000000
17 4.123105
18 4.242640
19 4.358898
``````

Improved version

The previous version only works for square roots of values ​​over 1. This second version accepts any positive value.

The improvement is in the calculation of the starting root. The idea is to test with values ​​1, 10, 100, 1000, etc. until a value is found that exceeds the parameter. Then we successively divide by 10 until we find a value that is less than the parameter.

The resulting value is the starting tentative root.

It also simplifies the detection of underflow , when the sum of the factor no longer contributes to the calculation of the root. In this case, it returns directly to the caller.

``````#define cuadrado(x) (x*x)

double root(double x) {

double factor = 1;

double raiz = factor;
double ant = raiz;
raiz += factor;
if (raiz == ant)
return raiz;
}

raiz -= factor;
factor /= 10;
}

return raiz;
}
``````

produce:

``````Raíz cuadrada de 0.0000001 es 0.000316