Question

En ruby, je veux convertir un flotteur à un int si elle est un nombre entier. Par exemple

a = 1.0
b = 2.5

a.to_int_if_whole # => 1
b.to_int_if_whole # => 2.5

En fait, je suis en train de ne pas afficher » .0" sur un nombre qui ne dispose pas d'une décimale. Je suis à la recherche d'une façon de faire

élégant (ou intégré)
def to_int_if_whole(float)
  (float % 1 == 0) ? float.to_i : float
end
Était-ce utile?

La solution 3

Ceci est la solution qui a fini par travailler comme je le veux à:

class Float
  alias_method(:original_to_s, :to_s) unless method_defined?(:original_to_s)

  def is_whole?
    self % 1 == 0
  end

  def to_s
    self.is_whole? ? self.to_i.to_s : self.original_to_s
  end
end

De cette façon, je peux mettre à jour la logique is_whole? (je semble que ce Tadman est le plus sophistiqué) si nécessaire, et il assure que partout une sortie à flotteur à une chaîne (par exemple, sous une forme), il semble que la façon dont je veux à (par exemple, pas de zéros sur la fin).

Merci à tous pour vos idées - ils ont vraiment aidé.

Autres conseils

Une façon simple serait:

class Float
  def prettify
    to_i == self ? to_i : self
  end
end

C'est parce que:

irb> 1.0 == 1
=> true
irb> 1 == 1.0
=> true

Ensuite, vous pouvez faire:

irb> 1.0.prettify
=> 1

irb> 1.5.prettify
=> 1.5

A sprintf une doublure ...

sprintf("%g", 5.0)
=> "5"

sprintf("%g", 5.5)
=> "5.5"

Je suis ne sais pas grand-chose à propos de Ruby.

Mais ceci est un affichage question. Je serais très surpris si les bibliothèques que vous utilisez ne sont pas un moyen de formater un numéro lorsque vous le convertir en une chaîne.

Il pourrait ne pas être un fourre-tout option de formatage qui fait exactement ce que vous voulez, mais vous pouvez configurer une méthode qui retourne true si le flotteur est la représentation flottante d'un nombre entier et faux autrement. A l'intérieur d'une routine de mise en forme que vous créez (vous suffit de le faire en une fois lieu) il suffit de changer la mise en forme en fonction de si cela est vrai ou faux.

Cette explique comment contrôler le nombre de chiffres qui apparaissent après la virgule décimale lorsque l'affichage d'un nombre.

Faites attention aux subtilités des représentations à virgule flottante. Math pourrait dire que la réponse est 3 mais vous pouvez obtenir 3,000000000000000000001. Je suggère d'utiliser un delta pour voir si le nombre est presque un nombre entier.

Bien que je suis d'accord avec le message ci-dessus, si vous devez faire ceci:

(float == float.floor) ? float.to_i : float

Si vous utilisez des rails, vous pouvez utiliser aide avec option number_to_rounded strip_insignificant_zeros, par exemple:

ActiveSupport::NumberHelper.number_to_rounded(42.0, strip_insignificant_zeros: true)

ou comme ceci:

42.0.to_s(:rounded, strip_insignificant_zeros: true)

Voici ma mise en œuvre horriblement hacktastic fourni à des fins éducatives:

class Float
  def to_int_if_whole(precision = 2)
    ("%.#{precision}f" % self).split(/\./).last == '0' * precision and self.to_i or self
  end
end

puts 1.0.to_int_if_whole # => 1
puts 2.5.to_int_if_whole # => 2.5
puts 1.9999999999999999999923.to_int_if_whole # => 2

La raison d'utiliser l'appel de style sprintf est qu'il gère beaucoup plus fiable flottante des approximations de point que la méthode ronde # Float tend à.

Je ne sais pas grand-chose à propos de Ruby soit.

Mais en C ++, je ferais ceci:

bool IsWholeNumber( float f )
{
    const float delta = 0.0001;
    int i = (int) f;
    return (f - (float)i) < delta;
}

Et puis je formater la précision de sortie sur cette base.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top