20142014. 1. 17. 09:32

Numeric 데이터를 Character 데이터로 변환하는 STR 함수를 사용할 때 유의해야 할 사항이 있습니다.

즉, Numeric 데이터가 형변환 되어 발생할 수 있는 오차 때문인데요. 아래 KB154000 예제를 먼저 살펴봅니다.

 

declare @x1 numeric(8,6), @x2 numeric(8,6)
select @x1 = 12.104375, @x2 = 12.128175

 

select str(@x1, 9, 5) STR, round(@x1, 5) ROUND
/*

12.10437    12.104380

STR 함수 수행 결과에서 반올림이 되지 않은 것을 확인할 수 있습니다.

*/

 

select str(@x2, 9, 5) STR, round(@x2, 5) ROUND

/*

12.12818     12.128180

하지만 이번 경우에는 기대한 것과 같이 반올림이 된 결과가 나타납니다

*/

 

 

PRB: STR() Inconsistent with Exact Numeric Data
http://support.microsoft.com/kb/154000/en-us

 

이와 같은 결과가 나타나는 원인은 아래 구문 형식을 통해 알 수 있듯이 첫번째 인수에 사용되는 값이 먼저 FLOAT 자료형으로 변환되기 때문입니다.

 

STR ( float_expression [ , length [ , decimal ] ] )

 

잘 알고 있듯이 decimal, numeric 에서 float 또는 real 로 형변환이 일어날 경우 정확한 값으로 변환되지 않고 근사값을 저장하게 되므로 반올림 연산 등에 사용될 경우 위와 같이 오차가 발생할 수 있습니다.

 

 

Float 자료형도 전체 자릿수를 고려하여 저장소 크기를 4byte(1-24) 또는 8byte(25-53) 로 정할 수 있는데 아래 예제와 같이 저장소 크기에 따라 또 다른 결과가 나타날 수 있음을 확인할 수 있습니다. 기본값은 53이므로 저장소의 크기는 8byte 가 됩니다.

 

declare @x1 numeric(8,4)
select @x1 = 9.465

 

SELECT STR(CAST(@x1 AS FLOAT(24)), 5, 2)
-- 9.47


SELECT STR(CAST(@x1 AS FLOAT(53)), 5, 2)
-- 9.46

 

 

정확한 숫자 연산이 필요한 경우 FLOAT 자료형은 사용하지 않아야 하며 STR 함수도 인수를 FLOAT 으로 변환하므로 위와 같은 오차가 발생할 수 있음을 고려해야 합니다.

 

 

[참고자료]

STR(Transact-SQL)
http://technet.microsoft.com/ko-kr/library/ms189527(v=sql.105).aspx

 

float 및 real(Transact-SQL)
http://technet.microsoft.com/ko-kr/library/ms173773(v=sql.105).aspx

 

decimal, float 및 real 데이터 사용
http://msdn.microsoft.com/ko-kr/library/ms187912.aspx

 

INF: Optimizing Comparisons with Numeric, Integer, and Others
http://support.microsoft.com/kb/198625/en-us

 

INFO: IEEE Floating-Point Representation and MS Languages
http://support.microsoft.com/kb/36068/en-us

 

 

작성자 : Lai Go / 작성일자 : 2014.01.17

Posted by Lai Go