LoginSignup
21
19

More than 5 years have passed since last update.

[ruby] 小数点以下x位にて切り捨て処理をしたい - メモ

Posted at

やりたい事

floor.rb
12.3456 => 12.34
255/13  => 19.61

こんな処理をしたい場合。
すぐに思いつくのは、floor関数。
Class: Float (Ruby 2.1.5) #floor

floor.rb
1.2.floor      #=> 1
2.0.floor      #=> 2
(-1.2).floor   #=> -2
(-2.0).floor   #=> -2

残念ながら、float型はfloor関数に引数(小数点以下指定)を指定する事ができません。
これは、浮動小数点問題があるからなのでしょうか。。。(?)

仕方ないので別の方法を探します。

BigDecimal

class BigDecimal

floor.rb
BigDecimal("1.23456").floor   # => 1
BigDecimal("-1.23456").floor  # => -2

BigDecimal("1.23456").floor(4).to_f   # => 1.2345
BigDecimal("15.23456").floor(-1).to_f # => 10.0

BigDecimal型にもfloor関数があり、こちらのfloor関数は引数に小数点以下を指定可能です。
これを使いましょう。

注意点

さきほどのやりたい事を、やってみます

floor.rb
[6] pry(main)> BigDecimal(12.3456).floor(2)
ArgumentError: can't omit precision for a Float.
from (pry):5:in `BigDecimal'

float型をそのまま引数で渡すとエラーとなってしまいます。
これはおそらく、float型を渡してる時点ですでに、浮動小数点問題により誤差が生じて正確な値じゃなくなっちゃうからだと思われます。

BigDecimalの引数にはStringを渡しましょう。

floor.rb
[7] pry(main)> BigDecimal('12.3456').floor(2)
=> #<BigDecimal:7f8cbf78fe30,'0.1234E2',18(27)>
[8] pry(main)> BigDecimal('12.3456').floor(2).to_f
=> 12.34

どうせStringを渡すのであれば、String/Integer/Floatなどには#to_dが用意されているので、これを使うともっとシンプルになりそうです
Class: String (Ruby 1.9.3)

floor.rb
[9] pry(main)> '12.3456'.to_d.floor(2)
=> #<BigDecimal:7f8cbf7e2428,'0.1234E2',18(27)>
[10] pry(main)> '12.3456'.to_d.floor(2).to_f
=> 12.34

もう一つのやりたい事もやってみます。

floor.rb
[35] pry(main)> (255.to_d/13.to_d).floor(2).to_f
=> 19.61

参考

[Ruby]消費税計算にはBigDecimalを使いましょう - Qiita
Class: String (Ruby 1.9.3)
class BigDecimal
小数第2位以下の切り捨て - ayaketanのプログラミング勉強日記

21
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
19