돈을 표기할 때는 왜 Double과 Float을 사용하지 않나요?


돈을 표기할 때는 double이나 float절대 사용하지 말라는 이야기를 들어왔습니다. 왜 그런건가요?

분명 좋은 이유가 있을거라 생각하지만, 그 이유가 뭔지 잘 모르겠네요.

  • 2016년 06월 13일에 작성됨

조회수 178


1 답변


좋아요
0
싫어요
채택취소하기

float과 double로는 우리가 돈을 셀 때 사용하는 10의 배수를 정확히 표현할 수 없기 때문입니다. 이 문제는 비단 자바에서 뿐 아니라, 부동소수점을 사용하는 모든 프로그래밍 언어에 해당하는 문제이며, 이는 컴퓨터가 부동소수점을 처리하는 방식에서 비롯된 문제입니다.

IEEE-754 부동소수점이 처리되는 방식은 이와 같습니다 : 부동소수점은 부호를 위한 한 비트, 지수를 저장하는 몇몇 비트와 가수를 저장할 나머지 비트들로 구성되어 있습니다. 이는 10.25와 같은 숫자를 1025 * 10^2와 같이 표현게 하는데, floatdouble의 경우, 앞의 예시와 같은 10의 배수가 아닌 2의 배수를 사용합니다. (따라서 164 * 2^-4이 됩니다.)

10의 배수에서도, 이러한 표기법은 가장 단순한 분수를 정확히 표현하지 못합니다. 예를 들어, 10의 배수로는 1/3을 표현할 수 없죠. 이를 표현하기 위해서는 무한하게 큰 음수의 지수와 무한한 양의 3을 저장해야 할 거고, 그건 불가능할 겁니다. 하지만, 돈을 표기하는 목적이라면 대부분의 시나리오에서는 10^-2까지만 저장하면 되기 때문에 그렇게 나쁘지만은 않습니다.

10의 배수로는 몇몇의 분수를 표현하지 못하는 것과 같이, 2의 배수로 정확하게 표현할 수 없는 분수들 또한 있습니다. 사실 (돈을 세기 위해 중요한) 0/100부터 100/100 사이의 100을 분모로 하는 분수 중 IEEE-754로 정확히 표현할 수 있는 부동소수점은 0, 0.25, 0.5, 0.75 그리고 1까지 다섯가지 경우밖에 없습니다. 나머지는 전부 조금씩 차이가 있죠.

돈을 double이나 float으로 표기하는 것은 처음에는 약간의 오차만을 보이기 때문에 괜찮아보일 수 있습니다. 그러나 정확하지 않은 수치에 사칙연산을 하면할수록 오차가 가중됨에 따라 더 많은 정확성을 잃게 될 겁니다. 이것이 바로 10의 배수의 정확도를 요구하는 돈을 세는데에 있어 float과 double이 적합하지 않은 이유입니다.

어떤 언어에서든 해결책은 센트 단위로 정수형을 세는 것입니다. 예를 들어, 1025는 $10.25달러가 되겠죠. 몇몇 언어에는 돈을 세는데에 사용될 타입을 내장하기도 합니다. 그 중, 자바는 BigDecimal 클래스를, C#은 decimal 타입을 갖고 있습니다.

  • 2016년 06월 14일에 작성됨

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close