Travailler avec des décimales dans Ruby on Rails 3
Je suis en train de calculer le prix net moyen d'un produit. J'ai, dans mon modèle de Produit :total_sold et :total_net_revenue. Faire droit à la division dans la méthode semble toujours 0. J'ai eu recours à l'aide de BigDecimal que j'ai pensé que c'était le problème ... mais avec ma dernière itération du code ci-dessous, je suis encore en train de zéro lorsque la réponse est un nombre décimal.
def avg_price
BigDecimal(total_sold.to_s) / (BigDecimal(total_net_revenue.to_s) / 100)
end
Chiffre d'affaires Net est en cents, c'est pourquoi j'ai diviser par 100. Quelqu'un peut-il point de ce que je fais mal ou devrait faire?
Pourquoi un
BigDecimal
? Ne serait pas to_f
sur la fin de ces valeurs, être assez?OriginalL'auteur Slick23 | 2011-01-19
Vous devez vous connecter pour publier un commentaire.
ou
ou
Ces trois méthodes donnent de plus en plus de précision, si vous le souhaitez. Rappelez-vous que le "prix moyen" est "la moyenne des prix de vente. C'est de l'argent-par-point si vous voulez faire de la division dans cet ordre précis.
OriginalL'auteur DigitalRoss
D'abord: Vous êtes à la division de la mauvaise façon.
100 éléments /$150 = .667 articles par dollar
vs
De 150 $ /100 = 1,50 $par élément
Deuxième: Comme d'autres langues, vous devez forcer l'un des numéros dans l'équation à une décimale, de sorte que le résultat est jeté comme un ainsi. Depuis votre chiffre d'affaires est un nombre entier, ce qui signifiait que tous les trois valeurs ont été nombres entiers, ce qui signifie que vous avez obtenu un nombre entier. Pour obtenir un nombre décimal, la fonte de l'un d'entre eux comme un nombre à virgule flottante.
En d'autres termes, pour obtenir ce que vous avez besoin, faites ceci:
OriginalL'auteur Shaun
Ce que vous faites est appelée division entière, ce qui écarte toute reste, comme il ne serait pas exprimable dans les entiers, par exemple:
Que les autres répondants ont mentionné, vous pouvez forcer une division à virgule flottante. Vous avez besoin de forcer le premier argument d'un flotteur (1) en l'appelant .to_f. Le deuxième argument sera automatiquement contrainte d'un flotteur, c'est à dire:
Noter qu'une fois que vous vous déplacez à des nombres à virgule flottante, le résultat, en général, n'est plus exacte. C'est pourquoi j'ai mis ~ 0.333.
Les détails précis sont plus impliqués. En binaire arithmétique à virgule flottante, ce qui est courant aujourd'hui dans les microprocesseurs, les puissances de 2 sont toujours exactes, je crois. Mais l'entier 3, par exemple, n'est plus représenté exactement, mais seulement à l'intérieur de la précision de la représentation à virgule flottante (généralement 1E-16 ou quelque chose du genre de "double précision).
Longue histoire courte, voici une règle de base: Si vous avez affaire avec les valeurs de la monnaie, où la précision des questions (jamais remarqué de 1 cent de l'écart sur une facture de téléphone?) ne pas stocker les résultats des calculs, et de ne pas stocker des valeurs dans floating points. Au lieu d'utiliser entier ou décimal types de données (à l'interne de stocker des chaînes de caractères). De calcul à virgule flottante résultats uniquement pour l'affichage et à la demande, si possible. Évitez d'ajouter des petites et grandes valeurs de l'ensemble une fois qu'ils sont les chars, et d'éviter les calculs enchaînés dans les flotteurs. Retravailler vos algèbre pour éviter les divisions jusqu'à la fin. Ruby prend également en charge Rationnelle type de données qui représente les fractions exactement et peut être utile.
Ces questions relèvent de la science de la "floating point de la propagation des erreurs", qui est l'endroit où vous pouvez rechercher plus d'informations si vous avez besoin d'.
C'est ce que j'ai trouvé fonctionne généralement mieux. Il y a aussi des gemmes, par exemple, l'argent gem, qui ajoute une certaine facilité à cette approche.
OriginalL'auteur Wolfram Arnold
Vous avez besoin de convertir vos valeurs qui sont entièrement cents (entiers) de flotteurs (nombres avec décimales) de sorte que les maths aura pour résultat un nombre flottant au lieu d'un entier.
Donc, en général, il fonctionne comme ceci:
OriginalL'auteur Andrew
Même si l'une des valeurs Float, le résultat sera le Flotteur.
Aussi, si vous à l'aide de Rails et de votre magasins de données dans un modèle précis, ActiveRecord a des méthodes, et vous n'avez pas besoin de calculer par vous-même.
Également disponible le minimum, le maximum, le nombre, la somme méthodes.
OriginalL'auteur wildDAlex