2010-02-13 13 views
9

J'ai une chaîne "1/16" Je veux convertir pour flotter et multiplier par 45. Cependant, je n'obtiens pas les résultats désirés.comment convertir une fraction de flotter en ruby ​​

Je suis en train de script/console

>> "1/16".to_f 
=> 1.0 
>> "1/16".to_f*45 
=> 45.0 

Comment puis-je obtenir le résultat souhaité de 2.81

image plus grande: J'ai vers le bas une goutte comme ceci:

<%=select_tag :volume, options_for_select(["", "1 g", "1/16 oz", "1/8 oz","1/4 oz", 
"1/2 oz", "1 oz", "1/8 lb", "1/4 lb", "Single", "Multi 5" ], "N/A") %> 

chaque fois que l'utilisateur sélectionne oz valeur alors je veux le multiplier par 45

donc je fais:

first, *rest = params[:volume].to_s.split(/ /) 
if rest.first=="oz" 
    @indprodprice = @prods.orig_price.to_i*first.to_f*28.3495 
else 
    @indprodprice = @prods.orig_price.to_i*first.to_f*453.59237 
end 
+0

je ne peux pas. Je reçois une chaîne de soumettre un formulaire dans ma page html. – ratan

Répondre

10

semble que vous allez devoir analyser la fraction vous. Cela fonctionne sur des fractions et des nombres entiers, mais pas des nombres fractionnaires (ie: 1 ½ ne fonctionnera pas.)

class String 
    def to_frac 
    numerator, denominator = split('/').map(&:to_f) 
    denominator ||= 1 
    numerator/denominator 
    end 
end 

"1/16".to_frac * 45 
+1

Que fait '&:'? – ratan

+3

C'est une petite main rubis. 'map (&: method)' fonctionne sur 'map {| obj | obj.method} ' – EmFi

17

Utilisation rationnelle

>> (Rational(*("1/16".split('/').map(&:to_i)))*45).to_f 
=> 2.8125 
+0

Je l'utiliserais car il garde une précision maximale jusqu'à ce que vous convertissiez en flottant. – hurikhan77

+0

Vous pouvez simplement faire '(Rational (" 1/16 ") * 45) .to_f' – Cyoce

10

@Farrel avait raison, et depuis Ruby 1.9 inclut rationnelle et chaîne a une to_r choses -method sont plus faciles:

puts ("1/16".to_r * 45).to_f #=> 2.8125 
puts ("1/16".to_r * 45).to_f.round(2) #=> 2.81 

En 2.0, il est devenu encore plus facile avec un littéral rationnel:

1/16r # => (1/16)