Problème d'arrondi impair avec le spécificateur de format printf de ruby
-
10-07-2019 - |
Question
Quelqu'un a-t-il des idées à ce sujet?
Quand nous courons:
printf ("%. 0f", 40.5)
Sur une fenêtre, le retour est "41". mais sur notre serveur de production Ubuntu, nous obtenons le "40"
La solution
Ressemble à un cas simple de imprécision binaire en virgule flottante . Sur une machine, vous obtenez 40.499999999 qui arrondit à 40; sur l’autre machine, vous obtenez 40.500000000001 qui arrondit à 41.
Si vous avez besoin de nombres exacts, vous ne devez pas utiliser de virgule flottante binaire. Vous pouvez utiliser une virgule décimale à virgule fixe ou une virgule flottante décimale.
Modifier: vous utilisez BigDecimal, vous dites. Pourquoi ne pas éviter toute conversion en float en utilisant #round
puis #to_i
? (Ou #floor
ou #ceil
au lieu de #round
... votre objectif n'est pas clair.)
b = BigDecimal.new("40.5")
print b.round.to_i # => 41
Autres conseils
Pourquoi ne pas utiliser .round
? Rails l’améliore même pour que vous puissiez spécifier la précision ( see API doc ).
utilisez% .0g à la place
La réponse de ScottJ n’explique pas votre problème - 40.5 est exactement représentable en binaire. Ce qui se passe probablement est la suivante: Windows printf " arrondit la moitié, " et printf "d'Urbuntu" arrondit la moitié même. "