PostgreSQL 자료형 비교 (numeric vs double)
비교 컬럼
- price_numeric : numeric type
- price_money : money type
- price_double : double type
비교
각각, 70.0007 에 해당하는 값과 3.33333333333333333333333 에 해당하는 값을 넣은 뒤에 select 쿼리를 날렸습니다.
select
name,
price_numeric,
price_numeric * 30000000 as "numeric",
price_money,
price_money * 30000000 as "money",
price_double,
price_double * 30000000 as "double"
from
float_test
결과
- numeric 의 경우 수가 커져도, 정확한 값을 유지하고 있음
- price_money 의 경우 정수형으로 저장이 되며, format 을 유지해줌 (3자리마다 콤마[,])
- double 의 경우 근사치를 반환함. 따라서 일반적인 계산에 적합함
아래에 정리된 공식문서에 따르면 부동 소수점 데이터 타입 에는 double 과 real 두가지가 있고 double 이 보다 더 정확하다.
이 값은 근사치이므로 반올림 되어 있는 값이다.
한편, numeric 의 경우 NUMERIC(precision, scale) 와 같이 이루어져 있는데
precision는 숫자 전체의 최대 정확도, scale은 소수점 이하 자릿수를 지정한다.
예를 들어서 NUMERIC(5, 2) 는 전체 5자리까지 표현이 가능하고, 소수점은 2자리까지 표현이 가능하여 전체 범위가 -999.99 ~ 999.99 가 된다.
범위만 높게 지정하면 numeric 이 double 보다 훨씬 정확한 값을 표현할 수 있지만, 계산시에 부동 소수점에 데이터에 비해서 매우 느려진다고 한다.
값 비교
select * from float_test where price_double = 3.33333333333333;
select * from float_test where price_numeric = 3.33333333333333333333333;
전자는 근사치로, 항상 오차 값이 있기 때문이며, price_numeric 는 정확한 값을 저장하고 있기 때문에 위와 같은 쿼리로 조회가 가능하다.
부동 소수를 비교 하는 방법
두 수를 뺀 값이, 오차 한도 내에 들어오는지를 확인해야 한다.
이 한도는 아래 북마크를 참고한다.
https://github.com/donghyeon0725/algorithm_java/tree/master/src/com/dataType/flo
오차한도 정하는 방법 : 숫자 a와 b가 같은지 비교할 때, 오차한도를 정하는 공식
"| a - b | / 둘중 더 큰 수"
이렇게 인데, 사실상 이를 적용하는 것은 매우 어려워 보이기 때문에 임의의 작은 값 0.000000000001 를 사용해서 비교하는 것도 방법이지 않을까...?
select * from float_test where ABS(price_double - 3.33333333333333) < 0.000000000001;
공식 문서
http://www.devkuma.com/books/pages/1442