¿Qué representa un doble en el servidor SQL?

335

Tengo un par de propiedades en C#que son doubley quiero almacenar estos en una tabla en SQL Server, pero di cuenta de que no hay doubletipo, por lo que es mejor para su uso, decimalo float?

Esto almacenará valores de latitud y longitud, por lo que necesito la precisión más precisa.

Gracias por las respuestas hasta el momento.

Xaisoft
fuente
Estas son las asignaciones de tipos de datos CLR a SQL Server: http://msdn.microsoft.com/en-us/library/system.data.sqldbtype.aspx
Achilles el
Hay un gran hilo en MSDN que describe la diferencia principal entre FLOAT y DECIMAL. En resumen, Float es aproximado y no puede representar algunos valores. Mira la respuesta aceptada.
Matthew Jones el

Respuestas:

387
float

O si quieres ir a la vieja escuela:

real

También puede usar float (53), pero significa lo mismo que float.

("real" es equivalente a float (24), no float / float (53).)

El tipo decimal (x, y) de SQL Server es para cuando desea números decimales exactos en lugar de coma flotante (que pueden ser aproximaciones). Esto contrasta con el tipo de datos "decimal" de C #, que se parece más a un número de coma flotante de 128 bits.

El tipo flotante de MSSQL es equivalente al tipo doble de 64 bits en .NET. (Mi respuesta original de 2011 decía que podría haber una ligera diferencia en mantisa, pero lo probé en 2020 y parecen ser 100% compatibles en su representación binaria de números muy pequeños y muy grandes; consulte https: / /dotnetfiddle.net/wLX5Ox para mi prueba).

Para hacer las cosas más confusas, un "float" en C # es solo de 32 bits, por lo que sería más equivalente en SQL al tipo real / float (24) en MSSQL que float / float (53).

En su caso de uso específico ... Todo lo que necesita es 5 lugares después del punto decimal para representar la latitud y la longitud dentro de una precisión de aproximadamente un metro, y solo necesita hasta tres dígitos antes del punto decimal para los grados. Float (24) o decimal (8,5) se ajustará mejor a sus necesidades en MSSQL, y usar float en C # es lo suficientemente bueno, no necesita el doble. De hecho, tus usuarios probablemente te agradecerán por redondear a 5 decimales en lugar de tener un montón de dígitos insignificantes para el viaje.

richardtallent
fuente
1
Dices flotar, David dice decimal, ahora estoy aún más confundido :)
Xaisoft
Estoy usando dobles en C # y estos valores serán valores de latitud y longitud en sus respectivas columnas.
Xaisoft el
1
Tengo que estar de acuerdo y admitir que estaba fuera de lugar. Me presentaron el decimal en el mundo IBM DB2, donde el decimal es un tipo de datos real, compatible con todos los tipos de código y la base de datos en las plataformas de IBM. No es que no sea un tipo de datos real en el mundo de la EM, pero no está soportado tan bien como en el campo de IBM. Perdón por crear alguna confusión.
DaveN59
2
"El flotante MSSQL no tiene exactamente la misma precisión que el tipo doble de 64 bits en .NET (ligera diferencia en mantissa IIRC), pero es una coincidencia lo suficientemente similar a la mayoría de los usos". ¿Tiene una referencia para esto? Por lo que puedo ver, ambos usan 53 bits de significado, usan 64 bits para almacenamiento y tienen el mismo diseño y significado de bits que IEEE 754.
codekaizen
2
También tengo mucha curiosidad sobre la pregunta planteada por @codekaizen (ligera diferencia en mantisa). ¿Tiene una referencia o una prueba que ejemplifique esto?
Mads Ravn
62

Además, aquí hay una buena respuesta para la asignación de tipos SQL-CLR con un gráfico útil.

De ese post (por David ): ingrese la descripción de la imagen aquí

Mazdak Shojaie
fuente
Debajo del enlace también de uso; tiene información adicional a la anterior, ya que muestra los procedimientos y enumeraciones de SqlDataReader (además de las comparaciones de tipos .NET y SQL) docs.microsoft.com/en-us/dotnet/framework/data/adonet/…
d219
15

flotador es el equivalente más cercano.

Enumeración SqlDbType

Para Lat / Long como OP mencionado.

Un metro es 1 / 40,000,000 de la latitud, 1 segundo es alrededor de 30 metros. Flotar / doble te da 15 cifras significativas. Con algo de aritmética mental rápida y poco fiable ... los errores de redondeo / aproximación serían aproximadamente la longitud de esta parada de llenado -> "".

gbn
fuente
1
¡Vende tu tecnología de pantalla a Apple y gana miles de millones! (La aritmética rápida me dice que tiene la resolución más extrema de la que he oído hablar, incluso en latitudes cercanas al Polo Norte / Sur; aproximadamente mil millones de veces más alta que la mía.)
Jonas Byström
10

Debería asignarlo a FLOAT (53); eso es lo que hace LINQ to SQL .

RichardOD
fuente
8

float en SQL Server tiene [editar: casi] la precisión de un "doble" (en sentido C #).

floates sinónimo de float(53). 53 son los pedazos de la mantisa.

.NET doubleusa 54 bits para la mantisa.

Euro Micelli
fuente
2
En realidad, IIRC, doble en .NET usa una mantisa de 52 bits y un exponente de 11 bits.
richardtallent
Estaré maldito; ¡tienes razón! Me pregunto qué hace SQL con el bit extra; no se usa para el exponente. Si lo hiciera, el exponente subiría a + -616 en lugar de + -308. Tal vez para rastrear NULL?
Euro Micelli
Ahora estoy confundido. Cada evidencia apunta a la idea de que usan el mismo formato (como todo lo demás en Windows). ¿Y por qué no lo harían? No puedo encontrar una declaración definitiva sobre la representación bit a bit en SQL Server (además de la página de ayuda para flotante). Publicaré una corrección si me entero.
Euro Micelli
5

Para el servidor SQL:

El tipo decimal es un número con signo de 128 bits Float es un número con signo de 64 bits.

La respuesta real es Float , estaba equivocado sobre decimal.

La razón es que si usa un decimal, nunca llenará 64 bits del tipo decimal.

Aunque decimal no le dará un error si intenta usar un tipo int.

Aquí hay una buena tabla de referencia de los tipos.

David Basarab
fuente
Ahora es aún más confuso con dos respuestas diferentes: p
Xaisoft el
1
No te confundas Esta respuesta es incorrecta. Decimal es un tipo de base 10; Float (en SQL Server y CLR) es un tipo base-2.
Michael Petrotta
3

Parece que puedes elegir y elegir. Si elige flotante, puede perder 11 dígitos de precisión. Si eso es aceptable, anímate, aparentemente los diseñadores de Linq pensaron que esto era una buena compensación.

Sin embargo, si su aplicación necesita esos dígitos adicionales, use decimal. Decimal (implementado correctamente) es mucho más preciso que un flotante de todos modos: no hay traducción desordenada de la base 10 a la base 2 y viceversa.

DaveN59
fuente
Esto es para almacenar valores de latitud y longitud. ¿Esto hace la diferencia?
Xaisoft el
Esto es simplemente incorrecto ... tanto float / float (53) en MSSQL como double en C # tienen aproximadamente 15 dígitos de precisión. No son exactamente lo mismo, pero lo suficientemente cerca. Decimal, por otro lado, es una exageración completa para almacenar un doble, y tiene que volver a la base 2 para todos los cálculos en SQL Server, y volver a C # como un doble.
richardtallent
Estoy corregido. Lo que estás diciendo tiene mucho sentido para mí. Decimal solo tiene sentido si lo mantiene como un valor decimal en todas partes. Pierde valor cada vez que realiza una conversión de base 10 a base 2 (y viceversa).
DaveN59
-2

A Floatrepresenta doubleen el servidor SQL. Puede encontrar una prueba de la codificación en C # en Visual Studio. Aquí lo he declarado Overtimecomo un Floatservidor SQL y en C #. Así puedo convertir

int diff=4;
attendance.OverTime = Convert.ToDouble(diff);

Aquí OverTimese declarafloat type

Md Shoriful Islam
fuente