2016-11-07 8 views
3

ユーザは文字列'67.99'を入力します。私は最終的にこれを整数6799に変換する必要があります。セントラルへのRubyフロート変換

つまり、stringで入力した通貨額をintegerデータタイプでセントに変換します。

私はこの問題が発生したことに気づく:

('67.99'.to_f * 100).to_i 
#=> 6798 

振る舞いを期待されていません。私は6798ではなく、6799という名前で保存する必要があります。

問題は100で、このフロート数を乗算します

'67.99'.to_f * 100 
#=> 6798.999999999999 

質問:どのように私は適切に小数を変換することができますが、整数に、文字列として入力されましたか?

例入力と出力:IMO

'67' #=> 6700 
'67.' #=> 6700 
'67.9' #=> 6790 
'67.99' #=> 6799 

:私はフロートが壊れていないことを認識していますので、これはthis questionの複製ではありません。

+1

金額を表すために浮動小数点数を使用しないでください。 '0.10 + 0.20'を計算するとどうなるか試してみてください... – spickermann

+2

状況に応じて[BigDecimal](http://ruby-doc.org/stdlib-2.3.1/libdoc/bigdecimal/rdoc/BigDecimal.html)もあります'BigDecimal.new('67 .99 ')' – tadman

+0

@spickermann私は浮動小数点数の計算を何もしていません。私は、通貨形式で入力された文字列値を取り出し、それをセンテンスとしてデータベースに保存します。一度そこに:私はそれが整数/セントとして格納された量の数学的計算を行うことは安全であることを知っています。すべての数学的計算はデータベースの整数値に基づいています。それを整数値に適切に変換するだけです。 – Neil

答えて

8

使用round

('67.99'.to_f * 100).round 
#=> 6799 

コメントで述べたように、このような文字列に対処するための潜在的により良い方法がある - BigDecimal classは:

(BigDecimal.new('67.99') * 100).round 
#=> 6799 

これは、多数のために、関連する次のようになります。

input = '1000000000000001' 

(input.to_f * 100).round 
#=> 100000000000000096 

(BigDecimal.new(input) * 100).round 
#=> 100000000000000100 
+1

あああ!私はそれが丸くなければならないことを知っていた!ありがとう! – Neil

+2

@Neilこれはテストケースでは機能しますが、 'to_f'は非常に基本的な変換方法です。ユーザーは「1,000.00」または「1,99」または「$ 100」と入力して驚くべき結果を得ることができます。 – Stefan

+0

良い点。私はそこに良いです。通貨入力のフォーマットは、それが有効な数字と期待される数字のフォーマットであることを保証するために事前に検証されます。 – Neil

関連する問題