🐈

【Ruby 3.4 Advent Calender】Integer#** の戻り値が大きくでも数値を返すようになる【13日目】

に公開

Ruby 3.4 Advent Calender 13日目の記事です。

これはなに

今年 2024年12月25日にリリースされる予定の Ruby 3.4 の新機能や変更点などを1つずつ紹介していく Advent Calender になります。
基本的には NEWS に載っている機能を紹介すると思うんですがここにない機能についても書くかもしれません。
また、記事を書いてる時点ではまだ Ruby 3.4 はリリースされる前なので Ruby 3.4 がリリースされた時点で機能が変わっている 可能性があるかもしれないので注意してください。
記事のまとめは ここを参照 してください。

Integer#** の戻り値が大きくでも数値を返すようになる

Ruby 3.3 では以下のように Integer#** の戻り値が大きい場合には警告を出力し Float::INFINITY を返します。

# warning: in a**b, b may be too big
p 2 ** 136279841 - 1
# => Infinity

一方で警告が出たり Float::INFINITY を返すのは Integer#** だけで次のように Integer#*Integer#<< では特に警告は出たりしません。

# no warning
(2 ** 32537661) * 2

# no warning
1 << 32537662

このあたりも踏まえて Ruby 3.4 では Float::INFINITY ではなくてちゃんと計算した数値が返って来るようになりました。

# 実際に出力しようとすると巨大すぎるので桁数だけ出力する
# no warning
p (2 ** 136279841 - 1).digits.count
# => 41024320

ちなみに 2 ** 136279841 - 1 は発見された最大の素数ですね。
これを Ruby で計算しようとしたら Float::INFINITY を返したのがこの対応を行うきっかけになっています。

関連

GitHubで編集を提案

Discussion