2013-05-17 3 views
1

int 유형의 두 변수가있는 프로그램이 있습니다. (6 소수점으로 인쇄 할 때 0.000001 의해) 제의 printf 작성된할당과 인쇄 사이의 다른 반올림

int num; 
int other_num; 

/* change the values of num and other_num with conditional increments */ 

printf ("result = %f\n", (float) num/other_num); 

float r = (float) num/other_num; 
printf ("result = %f\n", r); 

값은 두 번째의 printf 의해 작성된 값과 다르다.

는 분할 전에, 값은 다음과 같습니다

num = 10201 
other_num = 2282 

나는 15 소수점 이하 자릿수로 결과 번호를 인쇄했습니다. 그 수는 7 번째 소수점에서 갈라져 6 번째 차이점을 설명합니다. 여기

15 소수점 이하 자릿수로 숫자 :

4.470201577563540 
4.470201492309570 

나는 점 반올림 문제를 떠 알고 있어요,하지만 과제에와의 printf에서 수행 할 때 나는 동일하게 계산 된 결과를 기다리고 있었다 논의.

왜 이러한 기대가 잘못 되었습니까?

감사합니다.

+0

방금 ​​만든 테스트에서 일치합니다. 'num'과'other_num'의 값은 무엇입니까? 어떤 환경을 사용하고 있습니까 (호스트 아키텍처, 컴파일러 버전 등)? –

+0

나는 질문을 편집하고 숫자를 제공했다. 감사. – MyNameIsZero

답변

8

아마도 FLT_EVAL_METHOD은 시스템에있는 0 이외의 값일 것입니다.

첫 번째 경우, (float) num/other_num이라는 표현식은 공칭 유형이 float이지만, 더 높은 정밀도로 평가 될 수 있습니다 (x86의 경우 아마도 long double). 그런 다음 printf로 전달하기 위해 double으로 변환됩니다.

두 번째 경우에는 결과를 float 유형의 변수에 할당합니다. 그러면 과도한 정밀도가 떨어집니다. 그런 다음 floatprintf으로 전달되면 double으로 승격됩니다.

물론 실제 숫자가 없어도 이것은 모두 추측입니다. 좀 더 확실한 답을 원하면 문제에 대한 자세한 정보를 제공하십시오.

+0

감사합니다. 이건 재미 있네.나는 r 변수를 double로 선언하려고 시도했다. 그리고 두 프린트가 printf 호출과 같은 값을 갖기 시작했다. 이것은 당신이 쓴 것과 일치합니다. – MyNameIsZero

1

포인트는 프로그램 실행 중 표현식 결과의 실제 위치입니다. 컴파일러가 이런 종류의 최적화가 특정 경우에 가능하다고 결정하면 C 값은 메모리 (캐시 포함) 또는 레지스터에만있을 수 있습니다.

첫 번째 printf에서 표현식 결과는 같은 C 명령어에서만 사용되므로 레지스터에 저장되므로 컴파일러는 (바르게) 해당 변수를 덜 휘발성이있는 곳에 저장하는 것은 쓸모 없다고 생각합니다. 결과적으로 값은 아키텍처에 따라 double 또는 long double로 저장됩니다.

두 번째 경우 컴파일러는 이러한 최적화를 수행하지 않았습니다. 값은 스택 내에서 변수가 아니라 메모리에 저장됩니다. 따라서 동일한 값은 23 번째 유효 비트에서 잘린다.

더 많은 예제는 provided by streflop 및 해당 설명서입니다.