Ruby 小数点以下第n桁で切り捨てる方法


Ruby で 小数点以下第n桁で切り捨てる方法をメモしておきます。

0.81235 などのリテラル (Float) には floor という関数があり、 小数点以下の切り捨てが可能ですが、 小数点以下の桁を残して切り捨てることはできません。

環境

  • Ruby 2.2.3p173
  • OS: Ubuntu 15.04


解決法

調べたり考えたりした結果、 3つの方法が見つかりました。

BigDecimal を使う

BigDecimal なら floor という関数に小数点以下の桁数を指定して切り捨てることができます。 BigDecimal を作るときは 引数を String にする必要があります。

桁を操作する

小数点以下第n桁まで欲しければ、 \( 10^n \) 倍 してから \( 10^n \) で割ればいいです。

半分引いて四捨五入する

0.1 以上 0.2 未満 の数を 0.05 以上 0.15 未満 の数に投影して四捨五入すれば 小数点以下2桁を残して切り捨てたことになります。

これは num が正の数の場合には正しい値を返します。 num - 0.5 * 0.1 ** n が負の数になる場合は round が 四捨五入にならないことがあるからです。 (-0.5).round- 1 になります。

もし、 0 以上 で正しい答えを返すようにするなら次のような関数にします。

しかしこれはこれで、 最終結果が丸められずに 0.009999999999999998 (dec_floor(0.01, 2)) のようになることがあります。

失敗する方法

sprintf で文字列に変換する

sprintf で文字列に変換すると 自動的に四捨五入されてしまいます。

四捨五入されるので 上で紹介したように 半分引いて sprintf を使えば目的の文字列が取得できます。 数値として変換するわけではないのでおすすめはしません。