2010-06-17 12 views

Répondre

44

Cet argument a toujours deux côtés: les nombres décimaux et les nombres entiers. Les partisans des entiers soutiennent que les nombres décimaux peuvent ne pas être précis (en faisant des conversions) et que l'implémentation BigDecimal inclut des bogues, parfois même des segfaulting.

Pour mon propre projet, j'ai également ramassé des entiers, les enveloppant dans un conteneur personnalisé, convertissant des cents en montants «réels» et en retour. Au début, il semblait bien, après un certain temps, il est devenu très lourd à utiliser - suivi lorsque vous avez des cents, quand avec des chaînes formatées etc

Puis je suis revenu aux décimales - même format tout le temps, je peux facilement convertir le montant en cents si nécessaire, je reçois les différents algorithmes d'arrondi hors de la boîte. Im beaucoup plus satisfait des décimales.

Et pour résoudre les problèmes de décimales qui ne sont pas précis - lorsque vous googler, vous remarquerez que la plupart des bugs sont liés à la conversion des nombres décimaux en flotteurs :) Comme déjà mentionné, les flotteurs ne sont pas précis et vous ne devriez jamais convertissez votre décimal en flotteur. C'est la chose la plus importante que vous devez garder à l'esprit lorsque vous manipulez des décimales - vous ne voulez pas perdre de précision en effectuant des conversions. Oh et moi n'avons jamais rencontré de bugs avec ruby ​​1.8.7, 1.8.7 et 1.9.1 tout en utilisant BigDecimal de manière extensive.

+6

+1 "ne jamais convertir votre décimal en un flotteur" ... des choses étranges se produisent – tybro0103

10

Cela dépend.

Si vous effectuez des calculs pour les prix d'achat, utilisez un nombre décimal.
Si vous utilisez des mathématiques d'ingénierie, utilisez un flotteur.
Si vous stockez simplement les données, utilisez une chaîne.

52
add_column :table, :price, :decimal, :precision => 8, :scale => 2 

Le code ci-dessus serait votre meilleur pari.

+0

Comment puis-je le faire dans la ligne de commande? J'ai tapé "rails génèrent échafaud prix du produit: décimal" et il a créé une colonne avec: échelle 1. –

+2

Selon vos besoins, vous pouvez ajouter -> add_column: table,: devise,: chaîne,: default => 'USD ' – Tom

+0

Est-ce Rails 3? rails g migration Prix AddPriceToYourModel: décimal puis accédez à la migration générée et ajoutez les détails. – Tom

7

Je recommande d'utiliser des entiers pour les prix si possible. Beaucoup de gemmes populaires (telles que ActiveMerchant, Money) supposent l'utilisation d'entiers, et il est souvent préférable de stocker des unités de mesure dans une unité de base (comme des centimes).

+0

mais les entiers n'ont pas 13,25? –

+4

C'est pourquoi vous vous basez sur des cents. Donc, le 13,25 $ est stocké en tant que 1325 dans la base de données. Vous formatez le signe dollar et la décimale dans la vue. – sosborn

+1

À moins bien sûr que vous calculiez le prix de quelque chose qui utilise des fractions de cent, par exemple les prix du gaz. Ensuite, vous devriez avoir deux champs - un pour stocker la fraction comme un nombre entier et un autre pour vous dire combien de décimales le premier nombre devrait avoir et ... oh attendez que c'est idiot, utilisez simplement une décimale :) – MikeJ

10

Flotteurs ne sont pas exactes:

0.3 - 0.2 - 0.1 
=> -2.77555756156289e-17 

Ne les utilisez pas à moins que vous seulement stocker des valeurs.

Si vous devez effectuer des calculs, stockez le prix en cents sous la forme d'un nombre entier. Vous pouvez facilement les afficher en USD avec un assistant.

+2

omg que vraiment arrive. – jturolla

+2

c'est juste une chose précison. Il n'y a rien de mal avec la valeur. Que -2.7 * 10^-17 est très proche de zéro –

Questions connexes