가격의 데이터 타입에 대한 생각

sokojh·2022년 9월 25일
0

DB

목록 보기
3/3

주문 DB 스키마를 작성하다가

Price(가격) 칼럼을 만들려고 int 타입으로 간단하게 생각하고 넘길려고 했는데,
만약 가격이 소수점으로 표현된다면 정확하게 표현할 수 있을까?
라는 의문이 들었습니다.

역시나 찾아보니 float 자료형을 쓰면 안된다는 이야기가 많았습니다.

소수점을 float 실수형으로 그냥 표현하면 되지 왜 문제가 될까요?
컴퓨터가 저장하는 실수값

컴퓨터는 어떤 값을 저장할때 RAM에 저장을 하는데,


RAM 기억공간
사진과 같이 0과 1로 표현해서 저장합니다.

즉 어떤 수를 저장하고 싶다면 0과 1로 바꿔야하니 이진법으로 변환해서 저장하게 됩니다.

그렇다면 여기서 컴퓨터가 실수를 저장하려면 어떻게 저장할까요?

IEEE라는 곳에서 실수를 저장하는 방식에대해 설명한 것이 있습니다.

0과 1을 저장하는 32칸을 먼저 준비한 후

제일 첫번째 보라색 부분은 + 인지 - 인지 표현을 1과 0으로 표현해주고
예를 들어

5.125 을 메모리에 표현한다고 한다면

5.125를 이진법 변환 해준다. → 101.001

이진법 변환 해준뒤 왼쪽 첫번째 소수점으로 이동해준다 → 1.01001 x 22

1.01001 → 23~32칸 부분에 넣어줍니다.

22 을 이진법 변환 해줍니다. 2+127→ 10000001 2~9칸에 넣어줍니다.

이것이 실수를 표현하는 방식인데 여기에선 아주 큰 문제가 있습니다.

0.125 10진수를 2진수로 표현하면 0.001로 정리가 되지만

0.1과 같은 10진수를 2진수로 표현하면 순환소수가 되게됩니다. 0.1 → 0.000110011…

이런 숫자가 나왔을 때, 위에 방식으로는 32칸 뒤에 부분 값은 버려지게 됩니다.

그래서 버려지는 부분만큼 오차가 생기게 됩니다.

let a = 0.1;
let b = 1.1;
a+b == 1.2 // false

위와 같은 결과가 나오는 이유입니다.

해결방법

  1. 정말 정확히 계산하고 싶다면 정수로 → DECIMAL, CURRENCY와 같은 자료형이 있는데 DECIMAL과 같은 자료형은 정수(정확히는 문자열로 저장한뒤 정수로 변환)로 저장한뒤 소수점을 찍는 방식이라 가장 적합한 방식이라고 할 수 있습니다.

  2. 소수점을 사용하고 싶다면, 반올림 문법 사용

  3. double 자료형 사용(숫자 1개당 64칸을 사용하기 때문에 오차 범위가 거의 적음, 단점: 메모리 용량 2배 필요) → 하지만 정확성에 문제가 있음

profile
데이터팀에서 백엔드-데이터 엔지니어로 일하고 있습니다.

0개의 댓글