2012-08-31 3 views
2

내가 읽고 코드의 섹션이 있습니다.는 C에서 오답 ++

-5.000000000000722771452063564190e-01 2.710505431213761085018632002175e-20 
-5.000000000000722771452063564190e-01 

이해가되지 않습니다 :

문제는 이것의 결과는 사실에서 비롯됩니다. val2가 val1에 추가되지 않는 것으로 보이지만, val1의 분수 부분에는 분명히 val2이 추가 될 수있는 충분한 정보가 있습니다.

나는 어떤 문제가 있습니까?

저는 GCC 4.2를 사용하고 있습니다. G ++에서 IEEE 4 배 정밀도 형식을 사용합니까? 또는 다른 문제 (이 문제를 설명 할 수있는 80 비트 확장 정밀도와 같은 이유는 무엇입니까?).

+1

(첨가 생성 된 차분 진 긴 이중 포맷에 의해 표현의 범위를 벗어난다 때문에) 뭐죠'의 실제 값 val1' &'val2' ?? – perilbrain

+0

필수 Goldberg 링크 : http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html –

+0

실행중인 아키텍처 및 운영 체제는 무엇입니까? –

답변

4

글쎄, 내가 짐작 했어야 ... G ++에서 long double처럼 보입니다. 는 4 배 정밀도 형식으로 저장되지만 80 비트 확장 정밀도 형식을 사용하여 계산되므로 많은 숫자가 표시되지만 일부만 계산됩니다.

5

val1 및 val2가 올바르게 인쇄되면 출력은 정확 : -

-5.000000000000722771452063564190e-01 = -5.000000000000722771452063564190 X e^(-1) //or 10^(-1) 

^ denotes to the power of

2.710505431213761085018632002175e-20 = -5.000000000000722771452063564190 X e^(-20) //or 10^(-20) 

.. 출력 이유

Since val1 >> val2 
=> lim (val2/val1 -> 0) (lim is mathematical limit) .... eq (A) 

Consider y=val1+val2 
=> y= ((val1+val2)/val1)*val1 (rationalizing) 
=> y= {(val1/val1)+(val2/val1)} * val1 
=> y= {1+val2/val1}*val1 
=> y= {1+0}*val1 .........................................From eq (A) 
=> y= val1 

그게 -5.000000000000722771452063564190e-01

+0

실제로'e-01'은'* 10^(-01)'을 의미한다고 생각합니다. –

+0

@MatthieuM : 그렇습니다. Anon ymous 또한 알아두면, 4 배 정밀도 부동 소수점에서 사용할 수있는 정밀도의 자릿수는 ~ 35 자릿수 (두 숫자의 19 차 수위 차보다 훨씬 큽니다)입니다. 즉, 이들이 추가되어야 함을 의미합니다 . 그러나, 내 대답에서 언급 한대로 G ++에서 long double은 확장 된 정밀도 숫자 (약 19 자리의 정밀도)로 계산됩니다. 또한, 당신은 수학을 확인해야합니다 ... 그것은 많은 의미가 없습니다 (당신은 거기에 0으로 나누는 다른 실수들 중). –