하스켈의 반올림 계산법
어린 시절 반올림을 배울 때 중간값인 5 는 올린다고 배웠습니다. 예를 들어 소수점 한자리에서 반올림을 할 경우 1.4 는 1 이지만 1.5 는 2가 됩니다. 그 이유에 대해서 필자의 경우 0~4 는 내림, 5~9 는 올림으로 해야 5:5 로 공평하기 때문이라고 배웠습니다. 그 때는 그런가보다 하고 넘어갔었는데 사실 이것은 잘못된 이유입니다. 왜냐하면 0 은 반올림 대상이 아니기 때문이죠. 따라서 엄밀히 말하면 5를 그냥 올리는 것은 내림측에는 불공평한 방식입니다.
일상의 경우 이런 반올림 방식은 크게 지장이 없습니다. 그러나 보다 공정함이 요구되는 곳에서는 문제가 될 수도 있습니다. 예를 들어 은행에서 이자 계산 시 1원 단위를 반올림한다면 매번 5원을 10원으로 올리게 되면 그 때 발생하는 누적치는 상당할 것입니다. 또는 매우 정밀한 통계가 필요한 경우에도 중간값인 5를 무조건 올리는 것은 오차를 확대할 수 있습니다.
그래서 나온 반올림 방식이 'Round-to-even' 입니다. 이 방식은 중간값인 5 에 대해서 반올림 자리 바로 윗자리 숫자가 짝수에 가까워지도록 올림이나 내림을 수행합니다. 예를 들어 소수점 한자리에서 반올림을 할 경우 1.5 는 가장 가까운 짝수인 2 가 되도록 올립니다. 반면 2.5 는 가장 가까운 짝수가 2 이므로 내립니다. 따라서 1.5, 2.5, 3.5, 4.5, 5.5 는 각각 2, 2, 4, 4, 6 으로 반올림 됩니다. 중간값인 5 에 대해서는 올림과 내림을 번갈아가며 수행하는 것이 공평하다는 생각에서 나온 방법이지요.
하스켈에는 round 라는 함수가 있는데 주어진 실수값을 반올림하여 정수값으로 변환하는 함수입니다. 그리고 이 round 함수의 반올림 방식이 바로 round-to-even 입니다. 보통 C, C++, 자바 등의 언어들은 실수를 정수로 변환할 때 소수점 이하 값은 버립니다. 따라서 이런 언어에 익숙하다가 사전 지식 없이 하스켈에서 round 함수를 사용하면 혼란스러워 합니다. 마치 하스켈은 제멋대로 반올림을 하는것처럼 보이죠. 하지만 사실 알고보면 나름대로 심사숙고해서 round 함수를 만든 것이랍니다. ;)
Comments (0)