2012-08-02 4 views
2

long double double로 static_casting하면 gcc와 gdb가 이상하게 작동하는 문제를 조사하고 있습니다. 다음과 같은 코드가 있습니다 :gdb의 C++ static_cast가 gcc와 다른 결과를 반환합니다.

기본적으로 3/60이므로 결과는 0.05가되어야합니다. 단순한 double 값으로 작업 할 때 xStep의 값은 0.050000000000000003이므로 더 높은 정밀도와 12 바이트 long double을 사용하기로 결정했습니다. 위 예에서 xStepL의 값은 0.05000000000000000000067762635780344입니다. 이 값을 double으로 변환하면 실제로는 0.050000000000000003이됩니다. 그러나 gdb로 값을 검사하면 다음을 인쇄합니다.

(gdb) p xStep 
$1 = 0.050000000000000003 
(gdb) p static_cast<double>(xStepL) 
$2 = 0.049999999999999996 

결과가 다른 이유는 무엇입니까? 나는 실제로 그것이 두 번째 것이되기를 원한다. 누구든지 그 달성 방법을 알고 있습니까?

현재, GCC 4.3.4와 GDB 7.2.50을 사용하고 있습니다.

+0

'0.05'는 이진 부동 소수점으로 표현할 수 없으므로 실제 값은 '0.050000000000000003' ('0x1.999999999999ap-5') 또는'0.049999999999999996' ('0x1.9999999999999p-5') 중 하나가 될 것입니다. 큰 값은 '0.05'('0x1.9 ... ap-5')에 가깝기 때문에 그 값으로 끝내는 것이 더 낫습니다. – ecatmur

+0

이 값은 메모리 액세스의 오프셋으로 나중에 곱해지고 캐스팅됩니다. 불행하게도이 특별한 경우 (테스트 케이스와 절대 경계)에서 차이를 만들고 사용 가능한 메모리를 초과합니다. – t1mg

+0

메모리 문제를 해결할 수있는 방법으로는 bounds와 clamp를 테스트하는 것 (코드로 분기하는 방법)이나 메모리 블록 끝에 중복을 추가하는 방법이 있지만 액세스가 읽기 전용 인 경우에만 작동합니다. –

답변

1

나는이 문제가 static_casts이 동일한 값으로 호출되지 않는다고 생각합니다. 코드의 값은 고정밀 레지스터 값으로 호출되는 반면 gdb에서 호출 된 값은 메모리에서 long double을 사용합니다. 필자는 컴파일러가 정확히 할 수있는 위치가 정확한지 확신 할 수는 없지만, 이것이 하나라고 추측합니다. 따라서 응답은 한 엘프에 따라 달라질 수 있습니다.

+0

"고정밀 레지스터 값"이란 정확히 무엇을 의미합니까? 나는 또한 GCCs __float128 형식을 실험하고 같은 문제로 끝났다. – t1mg

+0

일반적으로 double을 사용한 계산은 고정밀 레지스터에서 수행 된 다음 메모리에 다시 저장할 때 낮은 정밀도로 다시 전환됩니다. IIRC는 종종 80 비트 중간 값 이었지만 현재 64 비트 프로세서에서는 다를 수 있습니다. –

2

이것은 gdb의 버그처럼 보입니다.

doublelong double에서 전송하는 명령 fstpl (8 바이트의 부동 소수점 스토어) 뒤에 fldt (열 바이트 부동 소수점로드)이다. 정밀도가 낮은 부동 소수점 저장소를 수행하면 0.05000000000000000000067762635780344에서 0.050000000000000003으로 이동하여 피연산자를 반올림합니다. 대신에 gdb가 피연산자를 자르고, 0.05000000000000000000067762635780344에서 0.049999999999999996으로가는 것 같습니다. 부동 소수점 16 진수에서 :

0x1.99999999999999999999ap-5 -> 0x1.999999999999ap-5 (gcc, correct) 
0x1.99999999999999999999ap-5 -> 0x1.9999999999999p-5 (gdb, incorrect) 

Discussion는이 GDB (7.4.50)의 최신 버전에서 해결을 나타냅니다.

+0

필자는 분 전에 데비안 위지 (Debian Wheezy)의 7.4.1을 테스트했고 같은 (잘못된) 결과를 보았습니다. 내가 더 최신 버전을 얻 자마자 나는 증명할 것이다. 답장을 보내 주셔서 감사합니다. – t1mg

+0

gdb (7.4.50)의 최신 주석과 함께 테스트했습니다. 그것이 버그라면, 그것은 고정되어 있지 않습니다. 잘못된 결과가 여기에 있습니다. – t1mg

관련 문제