c eclipse math gdb

c - ¿Por qué gdb evalúa sqrt(3) a 0?



eclipse math (5)

La raíz cuadrada de 3, según lo estimado por Wolfram Alpha:

1.7320508075688772935274463415058723669428052538103806280558...

Cuando hago sqrt(3) en C, se evalúa a 0. ¿Por qué?

EDIT4 : aquí es cómo puede reproducir este problema en GDB. Crea test.c siguiente manera:

#include <stdio.h> #include <math.h> int main() { printf("sqrt(3): %f/n", sqrt(3)); return 0; }

Compilar:

gcc -O0 -g -Wall -pedantic -ansi -lm -o test test.c

Ejecutar depurador:

gdb test

Introduce esto en la consola:

(gdb) break test.c:6 Breakpoint 1 at 0x400578: file test.c, line 6. (gdb) r Starting program: /home/pdedecker/Desktop/test Breakpoint 1, main () at test.c:6 6 printf("sqrt(3): %f/n", sqrt(3)); (gdb) print sqrt(3) $1 = 0 (gdb) s sqrt(3): 1.732051

Mi versión GDB es GNU gdb (GDB) SUSE (7.1-3.12) .


El problema no es la falta de declaración de la función (que no falta, ya que <math.h> ).

Al problema le falta información de depuración para el sqrt que realmente está utilizando. Sin esa información de depuración, GDB no tiene ni idea de qué tipo de parámetro pasar a sqrt() y qué devuelve.

Puede obtener la información de depuración requerida en muchas distribuciones de Linux instalando el paquete libc-debuginfo. Aquí está lo que veo en tal sistema:

gdb -q ./a.out Reading symbols from /tmp/a.out...done. (gdb) b main Breakpoint 1 at 0x400558: file t.c, line 6. (gdb) r Breakpoint 1, main () at t.c:6 6 printf("sqrt(3): %f/n", sqrt(3)); (gdb) p sqrt $1 = {<text variable, no debug info>} 0x7ffff7b7fb50 <__sqrt>

Nota: "no hay información de depuración"

(gdb) p sqrt(3) $2 = 0 (gdb) p sqrt(3.0) $3 = 0

Nota: coincide con su comportamiento. ¿Qué funciones sqrt tienen información de depuración?

(gdb) info func sqrt All functions matching regular expression "sqrt": File ../sysdeps/x86_64/fpu/e_sqrt.c: double __ieee754_sqrt(double); File s_csqrt.c: complex double __csqrt(complex double); File ../sysdeps/x86_64/fpu/e_sqrtf.c: float __ieee754_sqrtf(float); File w_sqrtf.c: float __sqrtf(float); File s_csqrtf.c: complex float __csqrtf(complex float); File ../sysdeps/i386/fpu/e_sqrtl.c: long double __ieee754_sqrtl(long double); File w_sqrtl.c: long double __sqrtl(long double); File s_csqrtl.c: complex long double __csqrtl(complex long double); File ../sysdeps/ieee754/dbl-64/mpsqrt.c: void __mpsqrt(mp_no *, mp_no *, int); File w_sqrt.c: double __sqrt(double); (gdb) p __sqrt $4 = {double (double)} 0x7ffff7b7fb50 <__sqrt>

Nota: __sqrt está en la misma dirección que sqrt , ¡pero GDB conoce su tipo!

(gdb) p __sqrt(3) $5 = 1.7320508075688772 (gdb) p __sqrt(3.0) $6 = 1.7320508075688772

Uno puede razonablemente argumentar que esto es un error en GDB. Siéntase libre de crear uno en GDB bugzilla .


Para llamar a una función sin información de depuración, debe indicar explícitamente a gdb el tipo para la devolución y los argumentos, utilizando un puntero a función. Por lo tanto, para su ejemplo:

(gdb) print ((double (*) (double)) sqrt) (3) $1 = 1.7320508075688772


Predigo que no hiciste #include <math.h>

Sin una declaración de función, C ajustará por defecto el valor de retorno de una función a int . Un número de punto flotante podría regresar como 0 dependiendo del tamaño de su int. C tampoco sabrá cómo convertir el argumento de la función. Por defecto pasará el argumento como el tipo que sea. Si pasa un entero a sqrt() , no se convertirá a doble, pero la función sqrt() interpretará el patrón de bits como double .


Tal vez llamando a sqrt no es compatible! Tal vez porque es una función libc. No sé por qué, pero la siguiente prueba muestra un comportamiento interesante:

double mysqrt(double x) { return sqrt(x) };

Luego en una sesión de gdb:

(gdb) p mysqrt(3) $1 = 1.7320508075688772 (gdb) p sqrt(3) $2 = -1209775368


#include <stdio.h> #include <math.h> int main() { printf("sqrt(3): %f/n", sqrt(3)); return 0; }

Salida:

josh@josh-ubuntu:~/scratch$ ./a.out sqrt(3): 1.732051