Qu'est-ce qu'un double serveur SQL?

335

J'ai quelques propriétés dans C#lesquelles se trouvent doubleet je souhaite les stocker dans une table dans SQL Server, mais j'ai remarqué qu'il n'y a pas de doubletype, alors quelle est la meilleure à utiliser, decimalou float?

Cela stockera les valeurs de latitude et de longitude, j'ai donc besoin de la précision la plus précise.

Merci pour les réponses jusqu'à présent.

Xaisoft
la source
Voici les mappages de types de données CLR à SQL Server: http://msdn.microsoft.com/en-us/library/system.data.sqldbtype.aspx
Achilles
Il existe un excellent fil sur MSDN décrivant la principale différence entre FLOAT et DECIMAL. En bref, Float est approximatif et ne peut pas représenter certaines valeurs. Regardez la réponse acceptée.
Matthew Jones

Réponses:

387
float

Ou si vous voulez aller à la vieille école:

real

Vous pouvez également utiliser float (53), mais cela signifie la même chose que float.

("réel" est équivalent à float (24), pas à float / float (53).)

Le type SQL Server décimal (x, y) est pour quand vous voulez des nombres décimaux exacts plutôt que des virgules flottantes (qui peuvent être des approximations). Cela contraste avec le type de données "décimal" C #, qui ressemble plus à un nombre à virgule flottante de 128 bits.

Le type float de MSSQL est équivalent au type double 64 bits dans .NET. (Ma réponse originale de 2011 indiquait qu'il pourrait y avoir une légère différence dans la mantisse, mais je l'ai testée en 2020 et ils semblent être 100% compatibles dans leur représentation binaire des très petits et très grands nombres - voir https: / /dotnetfiddle.net/wLX5Ox pour mon test).

Pour rendre les choses plus confuses, un "float" en C # n'est que de 32 bits, il serait donc plus équivalent en SQL au type real / float (24) dans MSSQL que float / float (53).

Dans votre cas d'utilisation spécifique ... Tout ce dont vous avez besoin est de 5 positions après le point décimal pour représenter la latitude et la longitude avec une précision d'environ un mètre, et vous n'avez besoin que de trois chiffres avant le point décimal pour les degrés. Float (24) ou décimal (8,5) correspondra le mieux à vos besoins en MSSQL, et l'utilisation de float en C # est assez bonne, vous n'avez pas besoin de doubler. En fait, vos utilisateurs vous remercieront probablement d'avoir arrondi à 5 décimales plutôt que d'avoir un tas de chiffres insignifiants à venir pour le trajet.

richardtallent
la source
1
Vous dites float, David dit décimal, maintenant je suis encore plus confus :)
Xaisoft
J'utilise des doubles en c # et ces valeurs seront des valeurs de latitude et de longitude dans leurs colonnes respectives.
Xaisoft
1
Je dois être d'accord et admettre que j'étais hors de la base. J'ai été initié à la décimale dans le monde IBM DB2, où la décimale est un véritable type de données, pris en charge par toutes les versions de code et la base de données sur les plates-formes IBM. Non pas que ce ne soit pas un vrai type de données dans le monde MS, mais il n'est pas pris en charge aussi bien que dans le camp IBM. Désolé d'avoir créé une confusion.
DaveN59
2
"Le flotteur MSSQL n'a pas exactement la même précision que le type double 64 bits dans .NET (légère différence dans la mantisse IIRC), mais il correspond suffisamment à la plupart des utilisations." Avez-vous une référence pour cela? Pour autant que je sache, les deux utilisent 53 bits de signification, utilisent 64 bits pour le stockage et ont la même disposition et la même signification que IEEE 754.
codekaizen
2
Je suis également assez curieux de la question posée par @codekaizen (légère différence de mantisse). Avez-vous une référence ou un test qui illustre cela?
Mads Ravn
62

En outre, voici une bonne réponse pour le mappage de type SQL-CLR avec un graphique utile.

De ce poste (par David ): entrez la description de l'image ici

Mazdak Shojaie
la source
Lien ci-dessous également utile; il contient des informations supplémentaires à celles ci-dessus, car il affiche les procédures et énumérations SqlDataReader (en plus des comparaisons de types .NET et SQL) docs.microsoft.com/en-us/dotnet/framework/data/adonet/…
d219
15

float est l'équivalent le plus proche.

Énumération SqlDbType

Pour Lat / Long comme OP mentionné.

Un mètre correspond à 1/40 000 000 de latitude, 1 seconde à environ 30 mètres. Float / double vous donne 15 chiffres significatifs. Avec une arithmétique mentale rapide et douteuse ... les erreurs d'arrondi / approximation seraient de la longueur de cet arrêt de remplissage -> "."

gbn
la source
1
Vendez votre technologie d'écran à Apple et gagnez des milliards! (L'arithmétique rapide me dit que vous avez la résolution la plus extrême dont j'ai jamais entendu parler, même à des latitudes proches du pôle Nord / Sud; environ un milliard de fois plus élevé que le mien.)
Jonas Byström
10

Vous devez le mapper sur FLOAT (53) - c'est ce que fait LINQ to SQL .

RichardOD
la source
8

float dans SQL Server a en fait [modifier: presque] la précision d'un "double" (dans un sens C #).

floatest synonyme de float(53). 53 est les morceaux de la mantisse.

.NET doubleutilise 54 bits pour la mantisse.

Euro Micelli
la source
2
En fait, IIRC, double en .NET utilise une mantisse 52 bits et un exposant 11 bits.
richardtallent
Je serai sacrément; vous avez raison! Je me demande ce que fait SQL avec le bit supplémentaire; il n'est pas utilisé pour l'exposant. Si c'était le cas, l'exposant monterait à + -616 au lieu de + -308. Peut-être pour suivre NULL?
Euro Micelli
Maintenant, je suis confus. Chaque élément de preuve indique l'idée qu'ils utilisent le même format (comme tout le reste dans Windows). Et pourquoi pas? Je ne trouve pas de déclaration définitive sur la représentation au niveau du bit dans SQL Server (à part la page d'aide pour float). Je publierai une correction si je le découvre.
Euro Micelli
5

Pour SQL Sever:

Le type décimal est un numéro signé sur 128 bits. Le flottant est un numéro signé sur 64 bits.

La vraie réponse est Float , j'avais tort sur la décimale.

La raison est que si vous utilisez une décimale, vous ne remplirez jamais 64 bits de type décimal.

Bien que décimal ne vous donnera pas d'erreur si vous essayez d'utiliser un type int.

Voici un joli tableau de référence des types.

David Basarab
la source
Maintenant, c'est encore plus déroutant avec deux réponses différentes: p
Xaisoft
1
Ne sois pas confus. Cette réponse est fausse. Decimal est un type de base 10; Float (dans SQL Server et le CLR) est un type de base 2.
Michael Petrotta
3

Il semble que vous puissiez choisir. Si vous choisissez float, vous risquez de perdre 11 chiffres de précision. Si c'est acceptable, allez-y - apparemment, les concepteurs de Linq ont pensé que c'était un bon compromis.

Cependant, si votre application a besoin de ces chiffres supplémentaires, utilisez décimal. Décimal (implémenté correctement) est de toute façon beaucoup plus précis qu'un flottant - pas de traduction désordonnée de la base 10 à la base 2 et inversement.

DaveN59
la source
C'est pour stocker les valeurs de latitude et de longitude. Cela fait-il une différence?
Xaisoft
C'est tout simplement faux ... float / float (53) en MSSQL et double en C # ont environ 15 chiffres de précision. Ils ne sont pas exactement les mêmes, mais assez proches. Decimal, d'autre part, est une surpuissance complète pour le stockage d'un double, et il doit revenir à la base 2 pour tous les calculs dans SQL Server et revenir à C # en tant que double.
richardtallent
Je me suis trompé. Ce que vous dites est parfaitement logique pour moi. Décimal n'a de sens que si vous le conservez partout comme valeur décimale. Vous perdez de la valeur à chaque fois que vous effectuez une conversion de la base 10 à la base 2 (et inversement).
DaveN59
-2

A Floatreprésente doubledans le serveur SQL. Vous pouvez trouver une preuve du codage en C # dans Visual Studio. Ici, je l'ai déclaré en Overtimetant que Floatserveur SQL et en C #. Ainsi je suis capable de convertir

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

Ici OverTimeest déclaréfloat type

Md Shoriful Islam
la source