평균값 프로그램에 관한 문제를 풀다 도저히 모르겠어서 질문 올
A Book on C 에서 1장 17번 문제를 도저히 모르겠네요..
17번 문제를 풀기위해서는 15,16번도 풀어야 하기 때문에
15,16번 문제를 같이 올립니다.
잘 하시는 분들께 도움을 얻고자 글을 올립니다.
-------------------------------------------------------------------------------
15. (스탠포드 대학의 Donald Knuth가 제안한 문제) 1.6절의 running_sum 프로그램에서 평균값을 계산하기 위해 먼저 숫자의 합을 구하고 더해진 숫자의 개수로 그 합을 나누었다. 다음 프로그램 better_average는 평균값을 더 좋은 방법을 사용하여 계산한 것이다.
/* Compute a better average. */
#include <stdio.h>
int main(void)
{
int i;
double x;
double avg = 0.0; /* a better average */
double navg; /* a naive average */
double sum = 0.0;
printf("%5s%17s%17s%17s\n%5s%17s%17s%17s\n\n",
"Count", "Item", "Average", "Naive avg",
"-----", "----", "-------", "---------");
for (i = 1; scanf("%lf", &x) == 1; ++i) {
avg += (x - avg) / i;
sum += x;
navg = sum / i;
printf("%5d%17e%17e%17e\n", i, x, avg, navg);
}
return 0;
}
이 프로그램을 수행시켜 보고 원리를 이해하여라. 이 새로운 알고리즘은 평균값을 계산하기 위해 다음 행을 사용하고 있다.
avg += (x - avg) / i;
이 알고리즘이 어떻게 평균값을 구하게 되는지 설명하여라. 힌트: 먼저 손으로 단순한 예를 계산해 보아라.
16. 이 연습 문제는 연습 문제 15번의 better_average 프로그램에서 sum이 컴퓨터에서 표현 가능한 값보다 더 큰 값을 가질 때 어떤 일이 발생하는지를 알아본다. (double 형이 가질 수 있는 값에 대한 상세한 것은 3.6절 "부동형"을 참조하여라.) data라는 파일을 만들어 다음 숫자들을 그 파일에 써넣어라.
1e308 1 1e308 1 1e308
그 다음 data 파일을 better_average의 입력 파일로 재지정한 후 수행시켜 보아라. 이 알고리즘의 장점을 알겠는가?
[ 해보시면 아시겠지만, avg의 값은 이상없이 잘 나오는 반면
navg는 infinity 또는 에러가 날 것입니다. 이것이 평균을 구하는 새로운 방법의 장점입니다 ]
17. (고급) better_ average 프로그램의 입력으로 위와 같은 큰 숫자가 아닌 평범한 숫자를 사용한다면, Average 열과 Naive Avg 열은 같을 것처럼 보인다. 두 열의 값이 달라지는 경우를 찾아보아라. 즉, sum이 오버플로 되지 않을 때에도 better_average가 실제로 더 좋은 방법이라는 것을 실험적으로 증명하여라.
http://cosmos.ssu.ac.kr/abc4h.html 여기가 책 홈페이지..입니다
=_=)a 17번을 아무리 생각해봐도 잘 모르겠네요..
오버플로우 이외에 어떤 장점이 있는지..
아시는 분은 도움의 손길을;;
좋은하루되세요 +_+)/
흐
흐
흠... 소스를 만들어 돌려 보았는데 모르겠넹..ㅡ.ㅡ;;
그리고 그것의 결과 인데요..
[root@ns test]# ./test
Count Item Average Naive avg
----- ---- ------- ---------
1 3 3.000000e+00 3.000000e+00
2 6 4.500000e+00 4.500000e+00
3 7 5.333333e+00 5.333333e+00
4 5 5.250000e+00 5.250000e+00
5 3 4.800000e+00 4.800000e+00
6 5 4.833333e+00 4.833333e+00
7 6 5.000000e+00 5.000000e+00
8 2 4.625000e+00 4.625000e+00
9 9 5.111111e+00 5.111111e+00
10 1 4.700000e+00 4.700000e+00
// 여기서 한번 틀리다고 스톱
11 2 4.454545e+00 4.454545e+00
12 7 4.666667e+00 4.666667e+00
// 여기서 또 한번 틀리다고 스톱
13 0 4.307692e+00 4.307692e+00
14 9 4.642857e+00 4.642857e+00
//여기서 또 한번 틀리다고 스톱
이상인데.. 머가 틀리다고 스톱이 된건지 모르겠네요.. 소스가 이상한가..ㅡ.ㅡ;;
환경은 리눅이 gcc 2.96에서 컴파일했습니다
흐
흐
보시면 아시겠지만..
소수점 아래 나온데 까지에서 반올림되어 출력되었습니다..
그래서 출력된곳 밑으로는 전부 000이라고 할수 있져..
감사합니다 ^^;
마이클러스트님께서 말하신대로 언더 플로우로 해서 해보니까
-infinity도 나오는군요..
답은 아마 그게 아닐가 싶습니다..
^^;
좋은하루되세요~!
+_+)a 키후리님도 감사합니다~
Music is the greatest communication in the world.
댓글 달기