C'est ce que je fais, ce qui fonctionne, qui fonctionne 99,999% du temps:
((int)(customerBatch.Amount * 100.0)).ToString()
8 Réponses :
Vous devriez vraiment utiliser des calculs décimaux pour l'argent.
((int)(580.55m * 100.0m)).ToString().Dump();
+1, les Docs recommandent même en utilisant décimal pour des calculs financiers / monétaires: MSDN.MicRosoft .Com / fr-US / bibliothèque / 364x0z75.aspx
Ignorer la méthode .Dump (). Copier et pâte de Linqpad.
Donc, vous vous suggérez d'utiliser: ((int) ((((décimal) CustomerBatch.amount * 100.0m)). Tostring ()
@Sophtware, vous pouvez supprimer le couler sur int
Je vais essayer cela et vous laisser savoir comment cela fonctionne. Merci!
Cela fonctionne: maths.trunate (((décimal) 580.55 * 100.0m) .Tostring ();
Cela pourrait fonctionner pour cette valeur, mais il y aura d'autres qui ne le font pas. Une fois que votre "wrapper" convertit SQL de l'argent au double des dommages est fait. Tu dois te débarrasser des doubles.
Vous pouvez utiliser décimal code> pour des calculs précis. Le double est le numéro de point flottant qui n'est pas garanti pour être précis pendant les calculs. P>
Ma suggestion serait de stocker la valeur en tant que nombre entier de Pennies et de prendre edit: strong> Quand j'ai écrit ce message, je n'ai pas vu que vous ne pouviez pas modifier le format de numéro. La meilleure réponse utilise probablement la méthode ronde que d'autres ont suggéré. P>
edit 2: strong> Comme d'autres ont souligné, il serait préférable d'utiliser une sorte de variable décimale de point fixe. C'est mieux que ma solution d'origine, car elle stockerait les informations sur l'emplacement du point décimal de la valeur où elle appartient au lieu de le code. P> Dollars_Part = Pennies / 100 Code> et cents_part = PENNIES% 100 code>. Cela évitera complètement les erreurs d'arrondies. P>
Je suppose que 580.55 est converti au 58054.99999999999999999999999999999999999999999999999. Vous voudrez peut-être écrire votre propre fonction qui convertit votre montant à un intégration avec une sorte d'arrondi ou de seuil pour que cela ne se produise pas. p>
Si tel est le cas, INT prend la partie entière plutôt que l'arrondissement. Que diriez-vous de quelque chose comme ((int) (rond (clearybatch.amount * 100.0))). ToString () alors?
Oui, cela fonctionnerait probablement (je ne connais pas le C # et je ne savais pas qu'il avait une fonction ronde intégrée).
Vous devinez sauvagement. 58054.99999999 ... N'est pas plus représentable avec précision comme un nombre de points flottant que 580.55.
Mon point est le numéro 580.55 n'est probablement pas enregistré comme 580,55. Il peut être représenté comme 580,55 lorsqu'il est imprimé. S'il est enregistré sous forme de nombre inférieur à 580,55 (peu importe ce qu'il est imprimé selon), il peut être arrondi par la conversion en int.
Vous ne devez vraiment pas utiliser une double valeur pour représenter la devise, en raison des erreurs d'arrondi telles que ceci. p>
Au lieu de cela, vous pourriez envisager d'utiliser des valeurs intégrales pour représenter des quantités monétaires, de sorte qu'elles soient représentées exactement. Pour représenter des décimales, vous pouvez utiliser un astuce similaire de stockage 580.55 code> comme valeur 58055 code>. P>
Non, la multiplication n'introduit pas les erreurs d'arrondi Mais toutes les valeurs ne peuvent pas être représentées par des nombres de points flottants. x.55 est l'un d'entre eux) p>
En d'autres termes, multiplier les nombres de points flottants sur un ordinateur fait i> introduisez des erreurs d'arrondi.
La première erreur d'arrondi s'est produite lorsque 580,55 ont été stockées dans un «double» comme 580.5499999999xxx. Le multipliant par 100 a donné 58054.9999999999xxx, qui n'est pas vraiment moins précis que 580.5499999999xxx.
Bien sûr, la multiplication des types de points flottants introduit des erreurs d'arrondi. Multiplier deux n bits Mantissas nécessite environ 2n bits pour stocker exactement le produit. Vous devez perdre des n bits pour stocker le résultat dans le même type.
Decimal a plus de précision qu'un double. Donner une décimale un essai. P>
http://msdn.microsoft.com /en-us/library/364x0z75%28vs.80%29.aspx P>
Essayez
((int)(Math.Round(customerBatch.Amount * 100.0))).ToString()
Traiter avec des erreurs ponctuelles flottantes: Stackoverflow .com / questions / 2248748 / ...
Voir cet article: docs.sun.com/source/806-3568/ncg_goldberg. HTML TL; DR: N'utilisez pas de flotteur ou double pour les calculs d'argent
La valeur provient d'une base de données SQL Server sous forme de valeur monétaire. La classe Wrapper d'objet utilise «double» pour ces valeurs, donc je ne peux donc pas changer le type de montant.
Vous devez utiliser une décimale au lieu de points flottants dans la mesure du possible lorsque cela concerne la monnaie.
En outre, le serveur ne calcule jamais les valeurs de ces champs de montants. Ils sont juste passés, je pense que c'est pourquoi l'objet Wrapper utilise «double» pour le type.
@SOPHTWARE: Mais vous pouvez sûrement extraire la valeur et le taper à la décimale?
@Sophtware: Vous devriez soulever un bogue sur la classe wrapper car il s'agit d'un bug de représenter une valeur monétaire en tant que double ou float.