J'ai fait des tests avec des calculs de points flottants pour minimiser la perte de précision. J'ai trébuché sur un phénomène que je veux montrer ici et j'espère avoir une explication.
Quand j'écris p> Le résultat est p> Lorsque j'écris la même formule et que je fais de la moulage explicite sur Le résultat est p> Jusqu'à présent, je pensais que les littéraux numériques avec des décimales sont automatiquement traités comme des valeurs code> flottant code> avec la précision appropriée. Casting vers float code> p>
Real code> montre le même résultat que la coulée sur
float code>. P>
Float Code> Obtenez une meilleure précision (ce qui ressemble à ironie pour moi :)? Li>
4 Réponses :
SQL Server utilise le plus petit type de données possible.
Lorsque vous exécutez ce script p> Vous verrez que SQL Server a implicitement utilisé un numérique (2, 1). DataType. pris à partir de livres SQL Server en ligne Type de données Conversion P> dans les déclarations transactives-SQL, une constante
avec un point décimal est automatiquement
converti en une valeur de données numérique,
en utilisant la précision minimale et l'échelle
nécessaire. Par exemple, la constante
12.345 est converti en une valeur numérique avec une précision de 5 et a
échelle de 3. p>
blockQuote> p>
La division de 60.0 convertit le résultat en numérique (8, 6).
Le calcul final convertit le résultat en numérique (17, 10). P>
Ah .. Je ne savais pas cette méthode jusqu'à maintenant. Merci beaucoup :)
Donc, il n'y a aucun moyen d'une extinction explicite pour obtenir le résultat attendu? Y a-t-il une autre façon de dire à SQL Server qu'un littéral donné est de type (par exemple)?
@Vvs, outre une fonte explicite comme vous le faites déjà, pas que je sache. SQL Server interprète toujours la valeur en tant que numérique. Le problème peut être atténué un peu si vous ajoutez une précision à vos valeurs comme 1.000000000000000000000000000000000000.
@Lieven: Avez-vous une sorte de documentation qui confirme votre déclaration selon laquelle "SQL Server interprète toujours la valeur en tant que numérique"?
@VSS: J'ai ajouté une référence à la documentation.
Oui, vous devez souvent les lancer pour flotter obtenir une meilleure précision. Mon prise dessus: p>
Pour de meilleures décimales de précision avant les calculs p>
La justification de l'article est défectueuse. Il est basé sur certaines valeurs arbitraires. Il serait facile de trouver un exemple de contre-exemple en faveur du type décimal. Ces revendications indiennes basées sur un exemple empirique sont des pièges en soi.
Je pense qu'il faut comprendre ce qui se passe dans les coulisses pour une référence future dans des cas similaires.
Les valeurs numériques littérales avec point décimal excluant la notation scientifique représentent le type de données décimal qui est stocké de type décimal qui est plus petit possible. Même citation que Lieven Keersmaekers de: https://msdn.microsoft.com/fr -US / Bibliothèque / MS191530% 28SQL.90% 29.aspx # _Decimal P>
dans les déclarations de transact-sql, une constante avec un point décimal est transformé automatiquement en une valeur de données numérique à l'aide du minimum précision et échelle nécessaire. Par exemple, la constante 12.345 est converti en une valeur numérique avec une précision de 5 et une échelle de 3. p> BlockQuote>
Les zéros de fuite à droite de point décimal spécifient l'échelle. Les principaux zéros laissés de point décimal sont ignorés. P>
Quelques exemples: p>
xxx pré> Un autre point à considérer est Type de données PRECÉDENCE . Lorsqu'un opérateur combine deux expressions de types de données différents, les règles de la priorité de type de données indiquent que le type de données avec la priorité inférieure est converti au type de données avec la priorité supérieure. Et pourtant, un autre point à considérer est si nous faisons des opérations arithmétiques sur des types décimaux que le type décimal résultant, c'est-à-dire la précision et l'échelle dépendent des opérandes et des opérations elles-mêmes. Ceci est décrit dans le document précision, échelle et longueur . P >
Ainsi, une partie de votre expression entre parenthèses p>
xxx pré> en utilisant des règles ci-dessus sur la précision et l'échelle des expressions décimales. En outre, l'arrondissement du banquier ou l'arrondi à même est utilisé. Il est important de noter que différents arrondis pour le type décimal et flotteur sont utilisés. Si nous continuons l'expression p>
xxx pré> de sorte que la partie de la divergence est due à une variation différente utilisée pour des types décimaux que pour le flotteur. P>
conformément à Les règles ci-dessus, il suffirait d'utiliser une seule montaise à l'intérieur de la parenthèse. Tous les autres littéraux seront promus pour flotter conformément aux règles de priorité de type de données. P>
1.0 / (1.0 / cast(60.0 as float))
Pour écrire une expression de flotteur constante, essayez d'utiliser la notation scientifique: p>
Le résultat est de 60. P> SELECT (1.0E0 / (1.0E0 / 60.0E0)) CODE> P>