77 votes

Utiliser des valeurs flottantes ou décimales pour le montant en dollars d’application comptable?

Nous sommes à la réécriture de notre héritage Système de Comptabilité en VB.NET et SQL Server. Nous avons apporté une nouvelle équipe .NET/ SQL Programmeurs de faire de la réécriture. La plupart du système est déjà rempli avec les montants à l'aide de Flotteurs. L'ancien système de la langue, j'ai programmé, n'ont pas de Float, donc j'aurais probablement utilisé un nombre Décimal.

Quelle est votre recommandation?

Devrait Flotter ou type de données Décimal être utilisé pour les montants en dollars?

Quels sont les avantages et les inconvénients pour l'un ou l'autre?

Un Con mentionné dans notre daily scrum est que vous devez être prudent lorsque vous calculer une somme qui renvoie un résultat de plus de deux positions décimales. Il semble que vous aurez à arrondir le montant à deux positions décimales.

Un autre Con est tous les affichages et imprimé montants doivent avoir un Format de Déclaration qui montre deux positions décimales. J'ai remarqué quelques fois où cela n'a pas été fait et les montants n'ont pas l'air correct. (c'est à dire 10.2 ou 10.2546)

Un pro est le Flotteur ne prend que 8 octets sur le disque où la Décimale serait prendre jusqu'à 9 bytes (Virgule 12,2)

111voto

TSK Points 816

Devrait Flotter ou type de données Décimal être utilisé pour les montants en dollars?

La réponse est facile. Jamais flotteurs. JAMAIS !

Les flotteurs ont été selon la norme IEEE 754 toujours binaire, seule la nouvelle norme IEEE 754R décimale définie formats. De nombreuses de la fraction binaire parties ne peut jamais égaler le décimal exact la représentation. Tout nombre binaire peut être écrite de la m/2^n (m, n des entiers positifs), d'un nombre décimal comme m/(2^n*5^n). En tant que binaires, manque le premier facteur de 5, tous les nombres binaires peut être exactement représentée par décimales, mais pas vice-versa.

0.3 = 3/(2^1 * 5^1) = 0.3

0.3 = [0.25/0.5] [0.25/0.375] [0.25/3.125] [0.2825/3.125]

     1/4       1/8     1/16       1/32

Si vous vous retrouvez avec un nombre soit supérieur ou inférieur au nombre décimal donné. Toujours.

Pourquoi cette question ? L'arrondissement des chiffres. Normal arrondissement signifie 0..4, 5..9. Donc, il n' importe si le résultat est soit 0.049999999999.... ou 0.0500000000... Vous savez peut-être que cela signifie 5 cent, mais l'ordinateur ne sait pas qui et des tours de 0.4999... vers le bas (le mal) et 0.5000... (à droite). Étant donné que le résultat des calculs en virgule flottante en contiennent toujours des petites erreurs, la décision est de la chance pure. Il devient désespérée si vous voulez décimal tour-de-même la manipulation avec des nombres binaires.

Pas convaincu ? Vous insistez sur le fait que, dans votre système de compte tout est parfaitement ok ? Les actifs et les passifs de l'égalité? Ok, puis de prendre chacun des nombres mis en forme de chaque entrée, de les interpréter et leur somme, l'indépendance du système décimal ! Comparez cela avec la mise en forme de la somme. Oups, il y a quelque chose de mal, n'est-ce pas ?

Pour ce calcul, d'une extrême précision et de fidélité a été nécessaire (nous avons utilisé Oracle FLOAT) afin que nous puissions enregistrer les "milliardième d'un penny" être courus.

N'aide pas à l'encontre de cette erreur. Parce que tous les gens supposent automatiquement que l'ordinateur sommes droite, quasiment personne ne vérifie de façon indépendante.

46voto

Nakilon Points 11635

23voto

Qberticus Points 20157

D'abord, vous devez lire ce Que Chaque informaticien Devriez Savoir Sur l'Arithmétique à virgule Flottante. Alors vous devriez vraiment envisager d'utiliser un certain type de point fixe / nombre en précision arbitraire paquet (par exemple, java BigNum, python décimal module) sinon vous serez dans un monde de souffrance. Alors à déterminer si l'utilisation du SQL natif de type decimal est assez.

Flotteurs/doubles existent(ed) afin d'exposer la rapide x87 fp qui est maintenant presque obsolète. Ne les utilisez pas si vous vous souciez de l'exactitude des calculs et/ou ne sont pas entièrement compenser leurs limitations.

10voto

Darrel Miller Points 56797

Tout comme un avertissement complémentaire, SQL Server et le .net framework utilisent un algorithme par défaut différente pour arrondir. Assurez-vous de que vérifier le paramètre MidPointRounding dans Math.Round(). .NET framework utilise un algorithme de banquiers par défaut et que SQL Server utilise l’arrondi algorithmique symétrique. Consultez l’article Wikipedia ici

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X