Domanda

In ruby, voglio convertire un galleggiante per un int se si tratta di un numero intero. Ad esempio

a = 1.0
b = 2.5

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

In sostanza sto cercando di evitare la visualizzazione" 0,0" su qualsiasi numero che non ha un numero decimale. Sto cercando un modo elegante (o built-in) per fare

def to_int_if_whole(float)
  (float % 1 == 0) ? float.to_i : float
end
È stato utile?

Soluzione 3

Questa è la soluzione che ha finito per lavorare il modo in cui voglio che:

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

In questo modo posso aggiornare il is_whole? logica (I sembra Tadman di è il più sofisticato), se necessario, e assicura che ovunque a uscite Float a una stringa (ad esempio, in una forma) appare come voglio a (cioè, zeri sul lato frontale).

Grazie a tutti per le vostre idee - hanno veramente aiutato.

Altri suggerimenti

Un modo semplice per sarebbe:

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

Questo perché:

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

Poi si potrebbe fare:

irb> 1.0.prettify
=> 1

irb> 1.5.prettify
=> 1.5

Uno sprintf uno di linea ...

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

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

Sono non so molto di Ruby.

Ma questo è un Display problema. Sarei estremamente sorpreso se le librerie che si sta utilizzando non hanno un modo per formattare un numero quando si converte in una stringa.

Non ci potrebbe essere un catch-all opzione di formattazione che fa esattamente ciò che si vuole, ma è possibile impostare un metodo che restituisce vero se il galleggiante è la rappresentazione galleggiante di un numero intero e false altrimenti. All'interno di una routine di formattazione che si crea (in modo da avere solo a fare questo in una volta posto) basta cambiare la formattazione in base a se questo è vero o falso.

Questo discute come controllare il numero di cifre che compaiono dopo il decimale durante la visualizzazione di un numero.

Attenzione per la complessità del floating point rappresentazioni. Math potrebbe dire che la risposta è 3, ma si può ottenere 3,000000000000000000001. Io suggerirei di usare un delta per vedere se il numero è quasi un numero intero.

Anche se mi piacerebbe tendenzialmente d'accordo con il post di cui sopra, se si deve fare questo:

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

Se si utilizza rotaie è possibile utilizzare helper number_to_rounded con l'opzione strip_insignificant_zeros, ad esempio:

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

o come questo:

42.0.to_s(:rounded, strip_insignificant_zeros: true)

Ecco la mia implementazione orribilmente hacktastic prevista per scopi didattici:

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 ragione per usare la chiamata sprintf stile è che gestisce floating point approssimazioni molto più affidabile rispetto al metodo rotonda Float # tende a.

Non so molto su di Ruby sia.

Ma in C ++, farei questo:

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

E poi mi piacerebbe formattare la precisione di uscita in base a questo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top