Différence entre numérique, flottant et décimal dans SQL Server


322

Quelles sont les différences entre numeric, floatet les decimaltypes de données et qui devraient être utilisés dans quelles situations?

Pour tout type de transaction financière (par exemple pour le domaine salarial), laquelle est préférée et pourquoi?


1
Le lien décimal et numérique ci-dessus doit être mis à jour vers docs.microsoft.com/en-us/sql/t-sql/data-types/… . Le lien ci-dessus n'existe plus.
Nigel Ainscoe du

1
Habituellement, lorsqu'il s'agit de sujets financiers, il est intéressant de travailler avec des types entiers , à l'exception de ceux à virgule flottante , et de stocker les valeurs en cents , au lieu de dollars , par exemple.
Pedro

Réponses:


494

utilisez les types de données float ou real uniquement si la précision fournie par decimal (jusqu'à 38 chiffres) est insuffisante

  • Les types de données numériques approximatifs ne stockent pas les valeurs exactes spécifiées pour de nombreux nombres; ils stockent une approximation extrêmement proche de la valeur. ( Technet )

  • Évitez d'utiliser des colonnes flottantes ou réelles dans les conditions de recherche de la clause WHERE, en particulier les opérateurs = et <> ( Technet )

donc généralement parce que la précision fournie par la décimale est de [10E38 ~ 38 chiffres] si votre nombre peut y entrer, et un espace de stockage plus petit (et peut-être la vitesse) de Float n'est pas important et traiter les comportements anormaux et les problèmes de types numériques approximatifs ne sont pas acceptable, utilisez Decimal en général .

informations plus utiles

  • numérique = décimal (5 à 17 octets) ( type de données numérique exact )
    • correspondra à Decimal dans .NET
    • les deux ont (18, 0) comme paramètres par défaut (précision, échelle) dans SQL Server
    • scale = nombre maximum de chiffres décimaux pouvant être stockés à droite du séparateur décimal.
    • veuillez noter que l'argent (8 octets) et smallmoney (4 octets) sont également exacts et mappent sur Decimal In .NET et ont 4 décimales ( MSDN )
    • décimal et numérique (Transact-SQL) - MSDN
  • réel (4 octets) ( approximatif type de données numériques )
  • float (8 octets) ( approximatif type de données numériques )
    • mappera vers Double dans .NET
  • Tous les types numériques exacts produisent toujours le même résultat, quel que soit le type d'architecture de processeur utilisé ou l'ampleur des nombres
  • Le paramètre fourni au type de données float définit le nombre de bits utilisés pour stocker la mantisse du nombre à virgule flottante .
  • Le type de données numériques approximatif utilise généralement moins de stockage et a une meilleure vitesse (jusqu'à 20x) et vous devez également tenir compte du moment où elles ont été converties en .NET

Types de données numériques exacts Types de données numériques approximatifs

source principale : Kit de formation auto-rythmé SCTM (examen 70-433): Développement de base de données Microsoft® SQL Server® 2008 - Chapitre 3 - Tableaux, types de données et intégrité déclarative des données Leçon 1 - Choix des types de données (directives) - Page 93


17
use the float or real data types only if the precision provided by decimal is insufficient- Je pensais que réel est MOINS précis que décimal, alors comment se fait-il que vous écriviez pour utiliser réel si la décimale est insuffisante?
BornToCode

7
réel est moins précis est donc pas recommandée à moins que le stockage grand plus grand nombre que décimales (> 10e38) est nécessaire ou des considérations espace .i deviner la précision ici dans les moyens de cotation des valeurs possibles et l' ampleur l'exactitude
Iman

12
@BornToCode La "précision" se réfère ici à la largeur des valeurs que vous souhaitez stocker. si vous avez besoin de stocker des valeurs entre 1e10 et 1e-10, ce decimalsera parfait . C'est une précision de 20. Si vous avez besoin de stocker des valeurs entre, disons, 1e20 et 1e-20, eh bien, decimal vous ne pouvez pas le faire. C'est 40 chiffres de précision. Vous ne pouvez jamais stocker 1e20 et 1e-20 dans le même decimalchamp. Au lieu de cela, vous pouvez utiliser float, qui stocke tout en interne comme un journal de base 2. Cela permet une gamme complète de précision dans un champ avec l'inconvénient que seuls les 8 premiers chiffres seront précis.
Bacon Bits

Je troisième commentaires de BornToCode et Iman. Je viens d'expérimenter (en utilisant SQL Server 2012), et il semble que la machine epsilon pour float (53), le type à virgule flottante de la plus haute précision, soit 2.22044604925031E-16. Vous en tireriez donc une quinzaine de chiffres significatifs. D'un autre côté, je peux obtenir 38 chiffres significatifs en décimal.
Stewart

"Utilisez le float..." - dit qui? Est-ce une citation ou votre opinion?
user443854

24

Instructions de MSDN: utilisation de données décimales, flottantes et réelles

La précision maximale par défaut des types de données numériques et décimaux est de 38. Dans Transact-SQL, le numérique est fonctionnellement équivalent au type de données décimal. Utilisez le type de données décimal pour stocker des nombres avec des décimales lorsque les valeurs de données doivent être stockées exactement comme spécifié.

Le comportement de float et real suit la spécification IEEE 754 sur les types de données numériques approximatifs. En raison de la nature approximative des types de données float et real, n'utilisez pas ces types de données lorsqu'un comportement numérique exact est requis, comme dans les applications financières, dans les opérations impliquant l'arrondi ou dans les contrôles d'égalité. Utilisez plutôt les types de données entier, décimal, monétaire ou smallmoney. Évitez d'utiliser des colonnes flottantes ou réelles dans les conditions de recherche de la clause WHERE, en particulier les opérateurs = et <>. Il est préférable de limiter les colonnes flottantes et réelles aux comparaisons> ou <.


Le nombre (fixe) de décimales est spécifié dans la Scalecolonne.
Cees Timmerman le

1
Si vous voulez `` exactement comme spécifié '', du point de vue des normes, il y a un avantage numericcar il ne stockera jamais avec plus de précision que vous ne l'auriez demandé: voir stackoverflow.com/a/759606/626804
Ed Avis

13

Pas une réponse complète, mais un lien utile:

"Je fais fréquemment des calculs par rapport aux valeurs décimales. Dans certains cas, le fait de lancer des valeurs décimales pour qu'elles flottent dès que possible, avant tout calcul, donne une meilleure précision."

http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/12/20/for-better-precision-cast-decimals-before-calculations.aspx


2
Ça n'a pas de sens. Toutes les autres réponses, avec les sources, disent que les types de données numériques ou décimaux sont précis, et les types flottants ou réels sont une approximation très proche. En raison d'une précision moindre, je peux comprendre que le lancer sur flotteur peut permettre des calculs plus rapides, mais pas une précision plus élevée.
cbaldan

3
Tous les types de données numériques peuvent subir un débordement et un sous-dépassement. Le débordement est une erreur explicite, cependant, le débordement est silencieux. Les caractéristiques du débordement pour decimalet floatsont différentes . Decimal préserve autant que possible le sous-dépassement en augmentant la précision ou l'échelle. Cependant, une fois que vous avez atteint la limite des chiffres significatifs en décimales, les sous-flux sont silencieux (et la précision est perdue). Float a une gamme d'échelle plus large possible, et ce sont les limitations d'échelle qui sont en fait la cause du sous-dépassement. Ainsi, le flotteur peut avoir une meilleure échelle. Néanmoins, il s'agit toujours d'un type inexact .
ErikE

13

Ils diffèrent par la priorité des types de données

Décimal et Numérique sont les mêmes fonctionnellement mais il y a toujours une priorité de type de données , qui peut être cruciale dans certains cas.

SELECT SQL_VARIANT_PROPERTY(CAST(1 AS NUMERIC) + CAST(1 AS DECIMAL),'basetype')

Le type de données résultant est numérique car il a priorité sur le type de données .

Liste exhaustive des types de données par ordre de priorité:

Lien de référence


7

Decimal a une précision fixe tandis que float a une précision variable.

EDIT (échec de lecture de la question entière): Float (53) (aka real) est un nombre à virgule flottante double précision (32 bits) dans SQL Server. Regular Float est un nombre à virgule flottante simple précision. Double est une bonne combinaison de précision et de simplicité pour de nombreux calculs. Vous pouvez créer un nombre très précis avec des décimales - jusqu'à 136 bits - mais vous devez également faire attention à bien définir votre précision et votre échelle afin qu'il puisse contenir tous vos calculs intermédiaires au nombre de chiffres nécessaire.


Vous n'avez pas précisé ce qui est préférable pendant que l'affaire est en cours pour une transaction financière et pourquoi?
priyanka.sarkar

Pour SQL Server 2008 et versions ultérieures, float (53) aka float est un nombre à virgule flottante double précision (64 bits), tandis que float (24) aka real est un nombre à virgule flottante simple précision (32 bits). docs.microsoft.com/en-us/sql/t-sql/data-types/float-and-real-transact-sql
M Kloster

4

Float est un type de données à nombre approximatif, ce qui signifie que toutes les valeurs de la plage de types de données ne peuvent pas être représentées exactement.

Decimal / Numeric est un type de données à précision fixe, ce qui signifie que toutes les valeurs de la plage de types de données peuvent être représentées exactement avec précision et échelle. Vous pouvez utiliser décimal pour économiser de l'argent.

La conversion de décimal ou numérique en flottant peut entraîner une perte de précision. Pour les types de données décimaux ou numériques, SQL Server considère chaque combinaison spécifique de précision et d'échelle comme un type de données différent. DECIMAL (2,2) et DECIMAL (2,4) sont des types de données différents. Cela signifie que 11.22 et 11.2222 sont de types différents bien que ce ne soit pas le cas pour float. Pour FLOAT (6) 11.22 et 11.2222 sont les mêmes types de données.

Vous pouvez également utiliser le type de données money pour économiser de l'argent. Il s'agit d'un type de données natif avec une précision de 4 chiffres pour de l'argent. La plupart des experts préfèrent ce type de données pour économiser de l'argent.

Référence 1 2 3


3

Le cas de Decimal

De quoi le besoin sous-jacent?

Elle découle du fait qu'en fin de compte, les ordinateurs représentent, en interne, des nombres au format binaire. Cela conduit inévitablement à des erreurs d'arrondi.

Considère ceci:

0.1 (decimal, or "base 10") = .00011001100110011... (binary, or "base 2")

Les points de suspension ci-dessus [...] signifient «infini». Si vous le regardez attentivement, il y a un motif répétitif infini (= '0011')

Donc, à un moment donné, l'ordinateur doit arrondir cette valeur. Cela conduit à des erreurs d'accumulation dérivant de l'utilisation répétée de numéros stockés de manière inexacte.

Supposons que vous souhaitiez stocker des montants financiers (qui sont des nombres qui peuvent avoir une partie fractionnaire). Tout d'abord, vous ne pouvez évidemment pas utiliser des entiers (les entiers n'ont pas de partie fractionnaire). D'un point de vue purement mathématique, la tendance naturelle serait d'utiliser a float. Mais, dans un ordinateur, les flottants ont la partie d'un nombre qui se trouve après un point décimal - la "mantisse" - limitée. Cela conduit à des erreurs d'arrondi.

Pour surmonter cela, les ordinateurs proposent des types de données spécifiques qui limitent l'erreur d'arrondi binaire dans les ordinateurs pour les nombres décimaux. Ce sont les types de données qui doivent absolument être utilisés pour représenter des montants financiers. Ces types de données portent généralement le nom de Decimal. C'est le cas en C #, par exemple. Ou, DECIMALdans la plupart des bases de données.


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.