2011-02-25 4 views
15

볼프람 알파 추정으로 3의 제곱근 : 나는 C에서 sqrt(3) 작업을 수행 할 때gdb가 sqrt (3)을 0으로 평가하는 이유는 무엇입니까?

1.7320508075688772935274463415058723669428052538103806280558... 

, 그것은 0 왜 평가?

EDIT4 : GDB에서이 문제를 재현하는 방법은 다음과 같습니다. 다음과 같이 test.c 만들기 :

#include <stdio.h>                                          
#include <math.h> 

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

컴파일 :

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

실행 디버거 :

gdb test 

콘솔에서이 입력 :

(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 

내 GDB 버전이 GNU gdb (GDB) SUSE (7.1-3.12)입니다.

+10

이 결과를 얻으려면 사용중인 코드를 표시하십시오. – birryree

+6

당신은''을 포함하고 있습니까? –

+0

+1 예레미야, 내가 그 오류에 직면 해있는 오래된 나이를 기억합니다 :) –

답변

16

문제는 누락 된 함수 선언되지 않습니다 (ISN : gdb를 세션에서 다음

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

을 당신은 <math.h>을 포함했기 때문에 실종되었습니다.)

실제로 사용하고있는 sqrt에 대한 디버그 정보가 누락되었습니다. 디버그 정보가 없으면 GDB는 sqrt()에 전달할 매개 변수 유형과 그 리턴 값에 대한 단서가 없습니다.

libc-debuginfo 패키지를 설치하면 많은 Linux 배포판에서 필요한 디버그 정보를 얻을 수 있습니다.

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> 

참고 : 여기에 내가 이러한 시스템에 표시되는 내용입니다 "디버그 정보"

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

참고 : 당신의 행동과 일치합니다. 무엇 sqrt 기능 합니까 디버그 정보가 있습니까?

(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> 

참고 : __sqrtsqrt 같은 주소이지만, GDB는 유형을 알고있다!

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

GDB의 버그라고 합리적으로 주장 할 수 있습니다. GDB bugzilla에 자유롭게 만드십시오.

+0

흥미 롭습니다. 나는 glibc-debuginfo (libc-debuginfo를 찾을 수 없었기 때문에 당신이 원하는 것을 바란다)를 설치했고'__sqrt'에 대한 함수 원형도 보았습니다. 'print __sqrt (3)'은 유효한 결과를 반환합니다. 버그를보고 한 경험이 거의 없으며 개발자에게 유용한 정보를 제공하기 위해 GDB의 내부 동작에 대해 충분히 알지 못한다는 것을 제외하고는이 버그를 GDB 개발자에게보고합니다. 어쨌든, 고마워요 ... 나는 당신의 대답을 받아 들였습니다! – Pieter

+0

GDB 버그 제출되었습니다 http://sourceware.org/bugzilla/show_bug.cgi?id=14757 –

0
#include <stdio.h>                                          
#include <math.h> 

int main() 
{ 
    printf("sqrt(3): %f\n", sqrt(3)); 

    return 0; 
} 

출력 :

[email protected]:~/scratch$ ./a.out 
sqrt(3): 1.732051 
+1

GDB에서 문제를 재현 할 수 있습니까? GDB를 실행하고 콘솔에'print sqrt (3.0)'을 입력하십시오. – Pieter

7

난 당신이 함수 선언없이 #include <math.h>

하지 않았다 것으로 예측, C는 int에 함수의 반환 값을 기본값으로 설정됩니다. 부동 소수점 숫자는 int의 크기에 따라 0으로 되돌아 올 수 있습니다. C는 함수 인수를 변환하는 방법도 모른다. 그것은 어떤 유형이든간에 그 인수를 디폴트로 전달할 것입니다. sqrt()에 정수를 전달하면 double로 변환되지 않지만 sqrt() 함수는 비트 패턴을 double으로 해석합니다.

+0

+1, 반환 값이 크게 달라질뿐만 아니라. 프로토 타입이 없으면 인수는'double'으로 변환되지 않습니다. 따라서'sqrt'는'double'으로 해석하고 레지스터에 double을 반환하거나 호출자가 다른 (정수) 레지스터에서 값을 취하는 이상한 비트 패턴을 보게됩니다. –

+0

'math.h'를 포함 시켰고'-lm'과 링크했습니다. – Pieter

0

아마도 sqrt를 호출 할 수 없습니다! libc 함수이기 때문일 수도 있습니다. 나는 깊은 이유를 모르겠지만, 다음 테스트는 재미있는 동작을 보여줍니다

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

디버그 정보없이 함수를 호출하려면 함수 포인터를 사용하여 gdb에 반환 및 인수의 형식을 명시해야합니다. 따라서 예를 들어 :

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

인쇄 (더블) SQRT ((더블) 3) 반환 을 $ 6 = 1 내가 의심 결과는 먼저 int로 변환 된 다음 double로 변환됩니다. – user1656671

관련 문제