tipos - sql server decimal format
En SQL Server, ¿por qué todos los decimales entre.00 y.99 se representan con precisión en los campos flotantes? (1)
Al convertir un float
a varchar
, SQL Server muestra un máximo de 6 dígitos de manera predeterminada . Un float
puede almacenar alrededor de 15 dígitos. Eso es más que suficiente para almacenar 1.1
hasta seis dígitos detrás del punto.
Es fácil mostrar la imprecisión con el tipo real
, que es un flotador con menos precisión. Cuando utiliza el estilo 2
de convert
para mostrar 16 dígitos :
select convert(varchar(max), cast(1.1 as real), 2);
-->
1.100000023841858e+000
El float
más preciso tiene suficientes ceros para mostrar:
1.100000000000000e+000
Ahora la print
parece usar el estilo 0 convert:
select convert(varchar(max), cast(1.3 as real), 0)
, convert(varchar(max), cast(1.3 as real), 1)
, convert(varchar(max), cast(1.3 as real), 2);
-->
1.3 1.3000000e+000 1.299999952316284e+000
Tal vez esto es algo como "ronda a seis dígitos y soltar ceros finales"? No estoy seguro, tendrías que experimentar.
No he encontrado una manera de hacer que SSMS muestre más de 16 dígitos. Pero un cliente lo suficientemente preciso puede mostrar que ningún float
puede almacenar 1.1
sin pérdida de precisión.
Para números decimales de la forma [x.00, x.99]
, donde x
es un número entero arbitrario (probablemente pueda adivinar aquí parte del contexto), los tipos de datos de coma flotante generalmente se consideran bastante inexactos y a veces peligrosos. En cambio, en los idiomas que tienen tipos de datos decimales, a menudo se prefieren los decimales. SQL es uno de esos idiomas.
Dicho esto, aquí hay un pequeño experimento interesante en SQL Server:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Table_1](
[SomeFloat] [float] NOT NULL
) ON [PRIMARY]
GO
INSERT INTO Table_1 VALUES (1.1)
SELECT SomeFloat FROM Table_1
SELECT SomeFloat + SomeFloat FROM Table_1
UPDATE Table_1 SET SomeFloat = SomeFloat + SomeFloat
SELECT SomeFloat FROM Table_1
Esto devuelve lo siguiente:
1.1
2.2
2.2
Eso no debería ser, ¿verdad? Se supone que x.1
no se puede almacenar como un número de coma flotante, no en SQL, ni en muchos idiomas. En cambio, ¿no debería redondearse, debido a las limitaciones cuando se trabaja con base-2?
Pero no lo es. Tampoco es algo más de la forma [x.00, x.99]
. Todos están representados con precisión, a pesar de usar un tipo de datos float
.
No puedo cambiar algunas cosas de float
a decimal
sin antes poder justificar que haya un problema en primer lugar. Estoy usando SQL Server 2012. ¿Se detecta automáticamente en problemas como este y convierte estos números en varchar
internamente o algo así? ¿Qué tan confiable es esto? Gracias.