Operazioni in virgola mobile con ruby

una domanda da principiante puro:

voglio moltiplicare due numeri float, con un numero di decimali
variabile, ed ottenere un risultato arrotondato alla seconda cifra
decimale:

es. 3.1416 * 6.35265 = 19.96

come faccio?

Ho trovato solo una istruzione ‘round’ ma mi arrotonda al numero intero
piu’ prossimo (20 in questo caso).

Ho trovato questa soluzione

((3.14166.35265100).round).to_f/100

funziona, ma mi sembra tanto contorta e credo che ci sia qualche altra
funzione piu’ semplice e veloce per questo caso.

Grazie a tutti, saluti ed auguri

Sono curioso anch’io di conoscere un modo migliore; quando è servito a me
ho usato sprintf("%.2f", float_num) e ha funzionato. Di sicuro non è molto
elegante…

:-/

antonio guerra wrote:

voglio moltiplicare due numeri float, con un numero di decimali
variabile, ed ottenere un risultato arrotondato alla seconda cifra
decimale:

es. 3.1416 * 6.35265 = 19.96
come faccio?

si può usare il metodo round della classe BigDecimal:

require ‘bigdecimal’
=> true
bd = BigDecimal((3.1416 * 6.35265).to_s).round(2)
=> #BigDecimal:b7c09c04,‘0.1996E2’,8(20)
bd.to_s(‘F’)
=> “19.96”

printf("%.2f",34.3456)

Oscar

Oscar Del ben wrote:

printf("%.2f",34.3456)

Oscar

Ma printf() e’ solo un comando formattazione per la stampa di un numero
arrotondato?
Se cosi’ fosse in memoria mi rimane il numero originale: io, invece,
devo avere un risultato arrotondato ai centesimi per inserirlo in una
tabella di MySql.
Trattandosi un un piccolo programmino di contabilita’ generale non posso
permettermi, comunque, imprecisioni nei numeri trattati, pena eventuali
squadrature dei conti fra dare ed avere (la quadratura dei conti e’
l’ossessione di noi ragionieri)

On Dec 26, 2007 8:52 PM, antonio guerra [email protected] wrote:

Ma printf() e’ solo un comando formattazione per la stampa di un numero
arrotondato?

Non credo ci sia un modo built-in, probabilmente ci sarà qualcosa in
qualche ext ma del resto le classi aperte di Ruby sono belle e se ti
serve solo quello basta sfruttarle :slight_smile:

class Float
def round(precision = nil)
if precision.nil? then
super()
else
if precision.is_a? Integer and precision > 0 then
decimals = 10 ** precision
(self * decimals).round / decimals.to_f
else
raise ArgumentError.new(“Argument must be a positive
integer”)
end
end
end
end

irb(main):015:0> f = 34.3456
=> 34.3456
irb(main):016:0> f.round
=> 34
irb(main):017:0> f.round(3)
=> 34.346
irb(main):018:0> f.round(2)
=> 34.35

antonio guerra wrote:

Oscar Del ben wrote:

printf("%.2f",34.3456)

Oscar

Ma printf() e’ solo un comando formattazione per la stampa di un numero
arrotondato?
Se cosi’ fosse in memoria mi rimane il numero originale: io, invece,
devo avere un risultato arrotondato ai centesimi per inserirlo in una
tabella di MySql.
Trattandosi un un piccolo programmino di contabilita’ generale non posso
permettermi, comunque, imprecisioni nei numeri trattati, pena eventuali
squadrature dei conti fra dare ed avere (la quadratura dei conti e’
l’ossessione di noi ragionieri)

Allora printf è un comando di output generico, comunque MAI usare in
nessun linguaggio numeri decimali per operazioni in qui hai bisogno di
essere preciso, usa invece i bignum piuttosto.

Comunuqe questa regola vale sempre

Il giorno 26/dic/07, alle ore 20:52, antonio guerra ha scritto:

Trattandosi un un piccolo programmino di contabilita’ generale non
posso
permettermi, comunque, imprecisioni nei numeri trattati, pena
eventuali
squadrature dei conti fra dare ed avere (la quadratura dei conti e’
l’ossessione di noi ragionieri)

Per evitare questo tipo di problemi quando l’arrotondamento è molto
importante di solito si preferisce memorizzare i centesimi piuttosto
che il valore con virgola, e dividerlo per 100 solo prima di
visualizzarlo.

Es. http://dist.leetsoft.com/api/money/

‘%.2f’ % (3.1416 * 6.35265)

Giovanni I. ha scritto:

importante di solito si preferisce memorizzare i centesimi piuttosto
che il valore con virgola, e dividerlo per 100 solo prima di
visualizzarlo.

Es. http://dist.leetsoft.com/api/money/

Esatto, i numeri in virgola mobile portano sempre con loro errori di
arrotondamento che purtroppo non sono mai trascurabili. Il mio consiglio
è di usare la classe BigDecimal della libreria standard.

Ciao,

Giovanni