코딩/기타

[C] 소수로 된 시간 계산하기 (+ 실수에서 오차가 생기는 이유)

rivermoon 2022. 10. 2. 22:11

친구한테 코딩 질문을 받아서 해결 과정을 적어보게 되었습니다.

문제는 다음과 같았습니다.

 

3.76 시간을 시간 : 분 : 초 형식으로 출력하시오.

#include <stdio.h>
int main(void){
    int hour, min, sec;
    double time = 3.76;
    //...
    return 0;
}

출력값 : 3.76시간은 3시간 45분 35초입니다.

 

 

해결 방법은 아래와 같습니다 :

더보기
더보기

우선 hour 변수에는 3.76의 정수 부분인 3이 들어가야겠죠.

hour = (int) time;
// 또는 hour = time / 1

으로 정수 부분이 들어가게 합시다.

 계산을 수월하게 하기 위해 time 변수에서 정수 부분을 빼 주어 소수 부분만 남도록 해 줍시다.

time -= hour

 이러면 3.76 - 3 = 0.76, time에는 0.76만 남게 되겠죠.

다만 time 변수를 바꾸어 버렸으므로 출력값을 표시할 때 문제가 생기게 됩니다.

이 줄을 작성하기 전에 

double o_time = time;

 이 줄을 작성하여 원래 시간을 기억해줄 변수를 만들어 해결해 줍시다.

 

min 변수에는 0.76시간을 분으로 환산한 값을 넣어야 합니다.

1시간은 60분이므로, 0.76시간은 0.76 *  60 = 45.6분이 됩니다.

 

time 변수에 60을 곱하여 45.6으로 만들어 줍시다.

time *= 60

그리고 min 변수에는 정수 부분인 45만 넣어주고, 정수 부분인 45를 time 변수에서 빼줍시다.

min = (int) time;
// min = time / 1;도 가능

time -= min

이러면 hour에는 3, min에는 45, time에는 45.6에서 45를 뺀 0.6이 남습니다.

1분은 60초이므로, 0.6분은 0.6 * 60 = 36, 즉 36초가 되어야 하겠죠.

time 변수에 60을 곱하여 36으로 만들어 준 후, 정수 부분을 sec 변수에 저장합시다.

 

time *= 60
sec = (int) time;
// 또는 sec = time / 1;

 

 코드를 완성하고 출력합시다.

#include <stdio.h>
int main(){
	int hour, min, sec;
	double time = 3.76;
	double o_time = time;
	
	hour = (int) time;
	time -= hour;
	
	time *= 60;
	min = (int) time;
	
	time -= min;
	time *= 60;
	
	sec = (int) time;
	printf("%.2f시간은 %d시간 %d분 %d초입니다.", o_time, hour, min, sec);
	

	
}

예상했던 대로 3시간 45분 36초가 나오지 않고, 35초로 뜨게 됩니다.

double time = 3.76으로 값을 넣었지만, 실제로 컴퓨터는 정확하게 3.76이라는 값으로 저장하지 않습니다.

이 부분에 대해 잘 설명된 유튜브 영상이 있으니, 보시는 것을 추천드립니다.

https://www.youtube.com/watch?v=-GsrYvZoAdA

 

코드를 작성하고 나서 출력시켜 보았을때 왜 이러한 문제가 생기는 지 궁금했었는데, 

이런 이유 때문이었다는 것을 새로 알게 되었네요. 코딩 알려주다가 새로운 것을 알아가게 되었습니다.