2016-09-17 4 views
0

다음은 C 프로그램의 스 니펫입니다.용어 순서를 변경하여 다른 답변을 얻는 이유

WARNING: sum = -5.551115e-17 at time index = 1 
WARNING: sum = 0.000000e+00 at time index = 1 

를 인쇄를 여기

printf(" WARNING: sum = %e at time index = %d\n",C[21]*X[0] + C[22]*X[1] + C[23]*X[2] + C[24]*X[3] + C[25]*X[4] + C[26]*X[5] + C[27]*X[6],TIME_INDEX); 
printf(" WARNING: sum = %e at time index = %d\n",C[21]*X[0] + C[27]*X[6] + C[22]*X[1] + C[26]*X[5] + C[23]*X[2] + C[25]*X[4] + C[24]*X[3],TIME_INDEX); 

이있어 대답은 제로에 정확히 같아야한다 :이 두 문장이 표현은 수학적으로 동일하더라도 다른 값을 줄 이유

은 누군가가 말해 주시겠습니까 . 요약에서 용어의 순서가 중요한 이유를 이해할 수 없습니다.

편집 : X [0] = X [6], X [1] = X [5], X [2] = X [4]를 명시 적으로 정의한다고 말해야합니다.

중심 차이 계수는 C [21] = -1.0/60.0; C [22] = 9.0/60.0; C [23] = -45.0/60.0; C [24] = 0.0/60.0; C [25] = 45.0/60.0; C [26] = -9.0/60.0; C [27] = 1.0/60.0;

+0

오버플로/언더 플로우 이벤트가 발생할 수 있습니다. 깨끗하게 컴파일 된 코드를 게시하고 문제를 표시하십시오. 관심있는 것은 배열 C []와 X []의 '유형'은 무엇이며 그 배열의 크기는 얼마나됩니까? – user3629249

+0

가능한 [부동 소수점 연산이 깨졌습니다] (https://stackoverflow.com/questions/588004). – user3386109

+0

@ user3629249 둘 다'double' 유형입니다. C의 배열에는 49 개의 값이 포함되어 있으며 X의 배열은 동적으로 할당되고 문제에 따라 다릅니다. – ThatsRightJack

답변

3

기계가 작업을 개별적으로 처리하고 제한된 정밀도로 처리하기 때문에 경우가 다릅니다. 길을 따라가는 각 단계는 값을 반올림하여 (추적 할 수있는 한) 사용 가능한 표현으로 반올림합니다.

한 가지 경우에는 동등한 용어가 정확하게 취소되었거나 다른 용어에서 크기가 너무 큰 값을 가진 경우 작은 용어 중 하나가 정확하게 적용될 수 없습니다. 따라서 대략 6 * 10^-17 또는 2^-54의 차이로 끝납니다. IEEE 754 64-bit floating point에서 유효한 가수의 유효 53 비트와 잘 일치합니다. 귀하의 오류는 실제로 그것이 될 수있는 한 작습니다.

큰 숫자는 필요하지 않으며/60 값 (1/3과 1/5는 모두 무한 이진수를 필요로합니다. 10 진수도 1/3).

을 올바르게 이해하는 것이 기본입니다. 프로세서가 이해하는 것보다 큰 값을 저장할 수있는 arbitrary precision (bignum)과 같은 더 적절한 표현이나 모든 값이 합리적 일 때 rational 양식을 사용하여 완화 할 수 있습니다. 이것이 데이터베이스가 별도의 decimal 유형을 갖는 경향이있는 이유입니다. 그러나 각각에는 한계가 있습니다. 1/60은이 예들의 합리적인면에만 적합합니다.

+0

알아두면 좋을 것. 따라서 sum이 정확히 0과 같아 지도록 프로그래밍의 관점에서 일반적인 관행은 무엇입니까? 인접한 조건이 취소되도록 주문이 일관성이 있는지 확인해야합니까? "if sum ThatsRightJack

+0

안전하다는 것은 논쟁의 여지가 있습니다. 오류가 얼마나 커 졌는지와 값을 잘못 해석 할 수있는 위험을 이해해야합니다. 이 경우 실제적으로 취소하는 것입니다. 일반적으로 부동 소수점 값의 정확한 비교는 신뢰할 수 없습니다. 실제로 입력 값의 크기에 따라 다르므로 0에 가까운 값이 중요한지 아닌지를 아는 것이 실제로 어렵습니다. 그 값은 약 2^-55의 중요한 결과 였을 것입니다. 1 근처의 값의 중요하지 않은 결과와 마찬가지로 쉽게 나타납니다. –

+0

입력 해 주셔서 감사합니다. – ThatsRightJack

관련 문제