실수 x가 0보다 크거나 같을 때 소수점 n째 자리에서 버림, 올림을 하는 방법을 알아보겠습니다.

 


 먼저, math의 floor와 ceil에 대해서 간단하게 알아봅시다. floor는 x보다 작거나 같은 수 중, 가장 큰 것을, ceil은 x보다 크거나 같은 정수 중 가장 작은 것을 돌려줍니다. -1.3이 있습니다. 이것보다 작거나 같은 수들에는 -2, -3, ... 이 있습니다. 이들 중 가장 큰 것은 -2이니, floor(-1.3)은 -2가 리턴됩니다. -1.3보다 큰 것은 -1, 0, 1 .. 이 있습니다. 이 중, 가장 작은 것은 -1이므로 ceil(-1.3)은 -1이 됩니다.

 

 다음에 -1보다 작거나 같은 수는 -1, -2, ... 가 있어요. 이 중 제일 큰 것은 -1이니 floor(-1)은 -1이 리턴됩니다. 반면에, -1보다 크거나 같은 수는 -1, 0, ... 이 있어요. 이 중 제일 작은 것은 -1이므로 ceil(-1)은 -1이 리턴됩니다.

 

 

 실행 결과는 위와 같습니다. 이제 소수점 z번째 자리에서 올림, 버림을 하는 경우를 생각해 봅시다.

 


 먼저 2.37을 생각해 봅시다. 소수점 둘째 자리에서 올림을 하는 경우 2.4가 됩니다. 어떤 과정으로 되는 것일까요? 소수점을 뒤로 1칸 이동시켜 봅시다. 그러면 23.7이 됩니다. 10을 곱한 상태입니다. 이 상태에서 ceil 함수를 쓰면, 24가 됩니다. 우리는 다시 소수점을 앞으로 1칸 이동시켜야 겠지요.

 

 이 때 10을 나누면 됩니다. 2.339를 생각해 봅시다. 소수점 셋째 자리에서 올림하는 경우 2.34가 됩니다. 이건 어떻게 해야 할까요? 이것도 어렵지 않습니다. 소수점을 뒤로 2칸 이동시킵니다. 그러면 233.9가 됩니다. 그 다음 ceil 함수를 쓰면 234가 됩니다. 다시, 소수점을 2칸 앞으로 이동시킵니다. 100으로 나눈다는 소리입니다. 그러면 2.34가 됩니다.

 

 이 과정을 그대로 코드로 옮기면 위와 같습니다. 여기서 z는 z+1번째 자리에서 올림한다는 의미입니다. 이 플로우를 도식화 시키면 아래와 같습니다.

 

 우측 이동을 하는 과정에서 곱했고, 원복하는 과정에서 / 연산을 이용했다고 생각하시면 됩니다. 이제 버림은 어떻게 해야 할까요? 2.337을 소수점 셋째 자리에서 버림하면 2.33이 나옵니다. 소수점을 2칸 우측으로 이동시키면 233.7이 나옵니다. 여기까지는 올림과 동일합니다.

 

 그런데, 그 다음에 ceil이 아니라, floor를 씁니다. 233.7보다 작거나 같은 수 중 제일 큰 것은 233입니다. 이제 소수점을 원복해야 겠네요. 233에 100을 나누면 2.33이 됩니다.

 

 이것을 그대로 코드로 옮기면 위와 같습니다. x에 2.337, z에 2을 넣으면 됩니다. 이는 2.337을 소수점 3번째 자리에서 버림하겠다는 의미입니다.

 

 

 이 과정을 도식화 시키면 위와 같습니다.

 

 이제 실행 결과가 제대로 나오는지 봅시다. 먼저, ceil(x, z)는 실수 x를 소수점 z+1번째 자리에서 올림합니다. floor(x, z)는 실수 x를 소수점 z+1번째 자리에서 내림합니다.

 

 v1은 2.34235였습니다. 소수점 4번째 자리는 3입니다. 여기서 올림하면 2.343이 나옵니다. 반대로 2.34235의 소수점 4번째 자리에서 내림하면 2.342가 나옵니다. 뒤에 35는 버려지게 됩니다. 다음에, v2는 0.74였습니다. 소수점 둘째자리에서 올리는 경우, 0.8이 나오겠네요. 반면에, 둘째자리에서 내림하는 경우 뒤에 4가 버려지므로 0.7이 됩니다. 소수점 1째자리에서 올림을 하는 경우, ceil, 내림을 하는 경우 floor와 같습니다. 2보다 크거나 같은 가장 작은 수도 2이고, 2보다 작거나 같은 수 중 가장 큰 수도 2이므로 맞게 출력됨을 확인할 수 있습니다.

 

 


 추가 질문. 반올림은 어떻게 하면 될까요? round 함수가 있기 때문에, 귀찮은 작업을 하지 않아도 될 것 같지만 실행을 시켜 보면 이야기가 달라집니다.

 

 2.335에서 소수점 3번째 자리에서 반올림 해서 2.34가 나올 거 같습니다.

 

 그런데, 실제로는 그렇게 나오지 않습니다. 왜? 2.335가 정확하게 2.335로 떨어지지 않기 때문입니다. 이보다 약간 작은 수이기 때문입니다. 실수의 한계점입니다. 따라서, 이 경우도 일정 자릿수만큼 곱한 다음에 round 처리를 한 후에 다시 원상태로 복구시켜야 합니다. 저 경우에는 2.335에 100을 곱해서 233.5로 만듭니다. 다음에 round 함수를 써서 234로 만듭니다. 그 다음에 원복시켜서 2.34가 되게 하면 됩니다.