3桁に切り捨てたい浮動小数点数がありますが、切り上げたくありません。
たとえば、1.0155555555555555
を1.015
に変換します(1.016
ではありません)。
Rubyでこれを行うにはどうすればよいですか?
BigDecimalに変換して、その上でtruncateを呼び出すこともできます。
1.237.to_d.truncate(2).to_f # will return 1.23
Ruby 2.4Float#truncate
メソッドは、オプションの引数として10進数の数字を取ります。
1.0155555555555555.truncate(3)
# => 1.015
千を掛ける、床、千で割る、フロート除算を行うようにしてください。
(x * 1000).floor / 1000.0
または、Ruby 1.9.2で、以前のバージョンでは使用できなかったバージョンのラウンドを使用して、
(x - 0.0005).round(3)
sidの答えは問題ありませんが、最初の要件を満たしていないため、Anwarのテストに失敗します。 Rubyが数値を簡単に変換しないように、rawを開始する必要があります。rawが取得するときにrawを開始するには、プレーンな文字列を使用する必要があります。
> "59.99999999999999999999" .to_d.truncate(2) => #BigDecimal:55a38a23cd68、 '0.5999E2'、18(45)> > "59.99999999999999999999" .to_d。 truncate(2).to_s => "59.99" > "59.99999999999999999999" .to_d.truncate(2).to_f => 59.99
私は今日この問題に自分で遭遇したので、今これを共有するだけです:)
このソリューションは、@ SidKrishnanによる素晴らしいBigDecimalトリックに基づいていますが、精度の問題に悩まされることなく、より大きなフロートを処理することもできます。
# Truncate a floating-point value without rounding up.
#
# trunc_float(1.999, 2) # => 1.99
# trunc_float(1.999, 0) # => 1.0
#
# @param value [Float]
# @param precision [Integer]
# @return [Float]
def trunc_float(value, precision)
BigDecimal(value.to_s).truncate(precision).to_f
end
#--------------------------------------- Test
describe ".trunc_float" do
def call(*args)
trunc_float(*args)
end
it "generally works" do
[
[[1, 0], 1.0],
[[1.999, 4], 1.999],
[[1.999, 3], 1.999],
[[1.999, 2], 1.99],
[[1.999, 1], 1.9],
[[1.999, 0], 1.0],
[[111111111.9999999, 3], 111111111.999],
[[1508675846.650976, 6], 1508675846.650976],
].each do |input, expected|
output = call(*input)
expect([input, output]).to eq [input, expected]
end
end
end
私はこれを行うためのより「計算的な」方法が答えの範囲内にないのを見ました。以下の方法の使用を検討できます。
これは、C/Java/Pythonなど)などの他のプログラミング言語でも機能します(ただし、キャスト構文は異なります)。
q = 1.0155555555555555
(q * 1000).to_i / 1000.0
=> 1.015