# Comparación de funciones y punto flotante

``````#include<stdio.h>
#include<stdlib.h>
#define abs(a) ((a)>0 ? a: -a)
#define eps_sqrt 0.00000000000001
#define it 100

float sqrt(float x)
/*The Square Root Function using the Newton's Method*/
{
int it_sqrt=0;
float a_sqrt = x/2;
while ((abs((a_sqrt*a_sqrt)-(x))>=eps_sqrt) && (2.0*a_sqrt != 0) && (it_sqrt<=it))
{
a_sqrt = a_sqrt - ((a_sqrt*a_sqrt)-(x)/(2.0*a_sqrt));
it_sqrt++;
}
return a_sqrt;
}

int main()
{
printf("%.5f\n", sqrt(5));
system ("pause");
}
``````

i tried using the Newton's iteration method to find the square root on Python and it worked, perfectly well. I'm new on C and I don't understand why this function didn't work for me. Whenever I run it, it returns "-1.#INF0A" Any help will be appreciated.

Edit: I tried changin the eps to `0.000001` y tampoco funcionó.

preguntado el 03 de mayo de 12 a las 17:05

I tried that but it still gives the same result -

wrong macro function abs argument. see my answer. -

don't use your own homebrew `abs` macro, it evaluates its argument twice. The C library has `fabs` for that. This usually a builtin, so the performance is the same but it is safe. -

## 4 Respuestas

Cambiando esta línea:

``````                a_sqrt = a_sqrt - ((a_sqrt*a_sqrt)-(x)/(2.0*a_sqrt));
``````

a

``````                a_sqrt = a_sqrt - ((a_sqrt*a_sqrt - x)/(2.0*a_sqrt));
``````

funciona para mi.

contestado el 03 de mayo de 12 a las 17:05

it worked but this doesn't follow the newton's method strictly - user1372984

it's approximately the bisection method - user1372984

Are you sure? It works for all integers from 0 to 100. Check the equations for Newton's method again. - fferen

it works but it is not the newton's method. the newton's method is x = x - f(x)/f'(x) thank you very much! i think C has its own precision problem, when i used the inbuilt function in the math.h library i got the same result. - user1372984

Try to use a bigger epsilon, maybe python uses doubles instead of floats.

contestado el 03 de mayo de 12 a las 17:05

Indeed. Epsilon for float should be more like 0.0000001 (7 decimal places) - Dr. Andrew Burnett-Thompson

``````double mysqrt(double x){
double eps=pow(10,-10);
double x0 = 0.0;
double x1 = x/2.0;
while(fabs(x1 - x0)>eps){
x0 = x1;
x1 = x0 + (x - x0*x0)/x0/ 2.0;
}
return x1;
}
``````

expansión macro
`abs((a_sqrt*a_sqrt)-(x))`
expansión `(((a_sqrt*a_sqrt)-(x))>0 ? (a_sqrt*a_sqrt)-(x): -(a_sqrt*a_sqrt)-(x))`
NG: `-(a_sqrt*a_sqrt)-(x)`

`abs((a_sqrt*a_sqrt- x))`
expansión `(((a_sqrt*a_sqrt- x))>0 ? (a_sqrt*a_sqrt- x): -(a_sqrt*a_sqrt- x))`

volver a escribir
`#define abs(a) ((a)>0 ? a: -a)`
a
`#define abs(a) ((a)>0 ? a: -(a))`

contestado el 03 de mayo de 12 a las 18:05

This is one of the rare cases where using `double` actually makes sense. Note that the precision of float is significantly lower than eps_sqrt:

``````[mic@mic-nb tmp]\$ cat tmp2.c
#include <stdio.h>
#include <math.h>

int main() {
double a = sqrtl(2.0);
printf("%1.20f\n", a - (float) a);
}
[mic@mic-nb tmp]\$ gcc tmp2.c; ./a.out
0.00000002420323430563
vs. your value of:
0.00000000000001
``````

So your program will, in most cases, never terminate.

contestado el 03 de mayo de 12 a las 17:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.