来年リリースする bigdecimal 3.2 はどうしようかな
おはようございます。mrkn です。2021年12月23日の朝です。ここでタイマーをセット。
この記事は Calendar for Ruby | Advent Calendar 2021 - Qiita の24日目の記事です。昨日は @tascript さんでした。
bigdecimal 3.1.1 をリリースした
みなさんは bigdecimal というライブラリをご存知でしょうか。このライブラリは任意の桁数の10進小数を正確に表現できる多倍長浮動小数点数を提供する標準添付ライブラリです。多くの環境で2進法による内部表現*1を採用する Float と違い、私たちが普段使ってる10進法での小数点付き演算で誤差が発生しないので、お金の計算をするときによく利用されていると思います。RDB の中では NUMBER 型で表現される数値を Ruby の世界に持ってくるときの表現としても利用されたりします。さらに、Float よりも細かい精度で計算したいときにも使われることがあります *2。
今朝、その bigdecimal の新バージョンである 3.1.1 をリリースしました。bigdecimal は Ruby の新しいバージョンがリリースされるタイミングに合わせて、同じメジャーバージョンとマイナーバージョンを持つ新バージョンをリリースすることにしています。つまり、毎年12月の後半のどこかで新バージョンがリリースされるのです。今回は Ruby 3.1 のリリースに合わせたので bigdecimal 3.1.1 がリリースされました。3.1.0 は昨日リリースされて、その直後にバグが見つかり、一晩で死にました。
bigdecimal 3.1.1 の主な変更点は以下の通りです。
BigDecimal#scale
で小数点以下の桁数を取得できるようになったBigDecimal#precision_scale
で全体の桁数と小数点以下の桁数を同時に取得できるようになったBigDecimal#quo
で結果の桁数を指定できるようになったBigDecimal#div
の第1引数が Float のときに結果の桁数を指定できるようになったKernel#BigDecimal
とto_d
による変換速度が向上した- いくつかのバグ修正
bigdecimal 3.2 をどうするか
bigdecimal 3.2 でも、手付かずの issue をいくつかやっつけたいです。現時点では次の issue が上がっています。
- BigMath.tan · Issue #81 · ruby/bigdecimal · GitHub
- BigMath.exp is slow for large argument. · Issue #82 · ruby/bigdecimal · GitHub
- Support large integral exponent in BigDecimal#power and BigDecimal#** · Issue #83 · ruby/bigdecimal · GitHub
- BigDecimal should accept a Float value without a precision · Issue #213 · ruby/bigdecimal · GitHub
あと、issue にしていませんが、ずっと昔からこれはやった方が良いんだろうなと考えているものがいくつかあります。
- 長い桁数の掛け算を Karatsuba と Toom3 で計算するようにして高速化する
- 掛け算が速くなったら、割り算を逆数の積で計算するようにして高速化する
- 円周率の計算アルゴリズムを Chudnovsky の公式に置き換える (現在のアルゴリズムは Machin の公式)
まぁ、これら3つは報告されているバグや機能提案を解決してからですね。
まとめ
bigdecimal 3.1.1 を紹介し、来年リリース予定の bigdecimal 3.2 についての展望を簡単に述べました。今後も bigdecimal をよろしくお願いします。バグを見つけたら CRuby の Redmine ではなく ruby/bigdecimal の GitHub Issue ページで報告してください。
*1:IEEE754で規定されている表現である場合が多いです。
*2:本当はmpfrライブラリのような内部表現が2進法の多倍長浮動小数点数を使う方が高速に計算できますが、Rubyに標準で付いてくる利便性から bigdecimal を利用する場合が多いのかもしれません