2011-07-21 22 views
6

El problema que tenemos es reducido a las dos afirmaciones siguientes:¿Inconsistencia de TSQL Round()?

select convert(float, (convert(float,5741.61)/convert(float, 196.00)) * convert(float,14.00)) as unrounded, round(convert(float, (convert(float,5741.61)/convert(float, 196.00)) * convert(float,14.00)), 2) as roundedTo2dp 

select convert(float, 410.115) as unrounded, ROUND(convert(float, 410.115), 2) as roundedTo2dp 

La primera instrucción utiliza flotadores para calcular un valor de 410.115, y también ese resultado con una ronda() a 2 decimales. El valor redondeado sale en 410.11.

La segunda instrucción usa el valor flotante 410.115 y también lo redondea a 2 decimales. El resultado redondeado sale como 410.12.

¿Por qué hay un redondeo hacia abajo y el otro redondeo cuando el valor redondeado es el mismo?

¿Cómo puedo obtener la primera instrucción para redondear a 410.12?

EDIT: disculpas por el formateo - stackoverflow no muestra ningún formato en esta máquina (muy extraño).

Respuesta

5

Los decimales son mejores con precisión que los flotadores. Si cambiaste el flotador por algo como DECIMAL (18,2), obtendrás lo que estás esperando y ya no necesitas llamar a la función circular.

select convert(decimal(18,2), (convert(decimal(18,2),5741.61)/convert(decimal(18,2), 196.00)) * convert(decimal(18,2),14.00)) as unrounded, round(convert(decimal(18,2), (convert(decimal(18,2),5741.61)/convert(decimal(18,2), 196.00)) * convert(decimal(18,2),14.00)), 2) as roundedTo2dp 

resultados en

unrounded roundedTo2dp 
410.12  410.12 

Enlace a la MSDN sobre los decimales. http://msdn.microsoft.com/en-us/library/ms187746.aspx

Espero que ayude ...

4

Los números no son iguales:

SELECT CAST(convert(float, (convert(float,5741.61)/convert(float, 196.00)) * convert(float,14.00)) AS BINARY(8)) 
UNION ALL 
SELECT CAST(convert(float, 410.115) AS BINARY(8)) as bin 

---- 
0x4079A1D70A3D70A3 
0x4079A1D70A3D70A4 
2

'float' es un tipo de datos número aproximado y por lo tanto no todos los valores en el rango de tipo de datos se puede representar exactamente.

Esto se basa en http://msdn.microsoft.com/en-us/library/ms173773.aspx.

Creo que esta es la razón por la cual hay un problema de redondeo al usar valores flotantes. ¡Nunca puedes estar 100% seguro!

Ej. Seleccione redondo (convertir (flotar, 1.5555), 2) - Da 1.56

Seleccione redondo (convertir (flotar, 1.555), 2) --¡Da 1.55!

Con un número tan simple hay una diferencia en el resultado esperado al usar el flotador.