2010-12-06 5 views
0

J'ai une base de données qui stocke des montants et qui est affichée dans une grille. J'ai un montant qui est entré comme 3 594 879,59 et quand je regarde dans le gridview je reçois 3 594 880,00.TSQL L'argent lancé comme flottant arrondit la précision

Le type SQL Money est le Money par défaut, rien n'a été fait dans SQL lors de la création de la table pour personnaliser le type Money. Dans Linq je jette le montant à un flotteur?

Qu'est-ce qui cause cela? Cela ne se passe que sur les grands nombres (ex: je mets 1.5 dans le db et 1.5 dans le gridview).

Répondre

1

Si la destination est un flottant 32 bits standard, alors vous obtenez exactement ce que vous devriez. Essayez de le conserver en tant qu'argent, ou changez-le en un entier à l'échelle, ou un point flottant à double précision (64 bits).

Un flotteur de 32 bits a six à sept chiffres significatifs de précision. Les flotteurs 64 bits ont juste moins de 16 chiffres de précision.

+0

Er ... no. Désolé, c'est faux. Ce n'est pas une question d'opinion, c'est tout simplement faux. Utilisez décimal - pas float ou double - pour représenter l'argent dans les applications .NET, car il utilise la représentation de base 10 et ne provoquera pas d'erreurs d'arrondi dues aux approximations de base-2. –

2

Convertissez le type SQL Money en décimal de type CLR. Decimal est un type numérique à virgule flottante qui utilise une représentation interne de base 10 et peut donc représenter n'importe quel nombre décimal dans la gamme sans approximation.

Il est plus lent que float, et vous échantiez la gamme pour la précision, mais pour tout ce qui implique de l'argent, utilisez décimal pour éviter les erreurs d'approximation.

EDIT: Comme pour "pourquoi est-ce qui se passe" - deux raisons. Premièrement, les nombres à virgule flottante utilisent une représentation interne de base-2, dans laquelle il est impossible de représenter exactement certaines fractions décimales. Deuxièmement, la raison pour laquelle les nombres à virgule flottante sont appelés à virgule flottante est qu'au lieu d'utiliser une précision fixe pour la partie entière et une précision fixe pour la partie fractionnaire, ils offrent un compromis continu entre l'amplitude et la précision. Les nombres où la partie intégrale est relativement petite - comme 1.5 - permettent d'assigner la plus grande partie de la représentation interne à la partie fractionnaire, et fournissent donc une plus grande précision. À mesure que la valeur de la partie intégrale augmente, les bits précédemment utilisés pour la précision sont maintenant nécessaires pour stocker la plus grande valeur entière et ainsi la précision de la partie fractionnaire est compromise.

Très, très crûment, il est comme avoir dix chiffres et vous pouvez mettre le point décimal où vous le souhaitez, de sorte que pour les petites valeurs, vous pouvez représenter des fractions très précises:

1.000000

mais pour des valeurs plus grandes, vous ne pas presque autant de précision fractionnelle disponible:

1234567890.2 

Pour plus de détails sur la façon dont cette en fait travaux, consultez la norme IEEE 754.

Questions connexes