2025/11/29 16:45 Schubfach: The smallest double-to-string implementation

やあ、ロボ子。今日は浮動小数点数の最短10進数表現についての論文を見つけたのじゃ。

博士、それは興味深いですね。浮動小数点数を正確に10進数に変換するのは難しいと聞いたことがあります。

そうなんじゃ。昔はDragon4みたいな多倍長演算アルゴリズムが主流だったけど、最近はRyuとかSchubfachみたいな高性能なのが出てきたみたいじゃぞ。

Schubfachアルゴリズムですか。初めて聞きました。どのような仕組みなのでしょうか?

Schubfachは、ラファエロ・ジュリエッティさんが考えたアルゴリズムで、二進浮動小数点数を最短で正確な10進数文字列に変換する方法なんじゃ。ピジョンホール原理っていうのを使うらしいぞ。

ピジョンホール原理ですか。詳しく教えていただけますか?

簡単に言うと、もしn個の箱にn+1個のものを入れたら、少なくとも1つの箱には2つ以上のものが入る、っていう考え方じゃ。Schubfachでは、これを使って最適な10進数の指数を効率的に決めるんじゃ。

なるほど。JavaのBigIntegerのような高コストな任意精度演算を避けて、固定精度整数演算で実現しているのもポイントみたいですね。

そうそう。Nadezhinさんの結果で、丸め区間の重要な境界が整数に極端に近いことはないって保証されてるのも大きいみたいじゃな。

丸め区間というのは、浮動小数点数がある特定の値に丸められるすべての実数を含む範囲のことですね。

その通り!Schubfachは、この丸め区間が色々なスケールの10進数グリッドとどう交差するかを調べることで、最短の10進数を見つけ出すんじゃ。

実装も興味深いです。IEEE-754の形式から符号、指数、仮数部を抽出して、固定小数点演算で10進数の指数を計算するんですね。

Pythonスクリプトで事前計算されたテーブルから10の累乗の近似値を持ってくるのも面白いところじゃな。最大4つの候補から選ぶのも効率的じゃ。

パフォーマンスはどうなのでしょうか?

dtoa-benchmarkだと、Ryuと同程度かそれ以上みたいじゃ。Dragonboxよりは少し遅いけど、sprintfよりはずっと速いみたいじゃぞ。

sprintfより21倍も速いんですか!それはすごいですね。

しかも、最新のアルゴリズムが約200行のC++コードで実装できるってのが驚きじゃな。uint128_tとかを使えば、もっと速くなる可能性もあるみたいじゃ。

浮動小数点数の変換は奥が深いですね。今日の話を聞いて、Schubfachアルゴリズムに興味が湧きました。

じゃろ? ちなみに、Schubfachはドイツ語で「引き出し」って意味なんじゃ。引き出しを開けて、最適な10進数を見つけ出すイメージじゃな!

面白いですね!まるで宝探しみたいです。

そうじゃ! でも、浮動小数点数の世界は、時々、底なし沼にハマることもあるから気をつけろよ?

はい、肝に銘じます!

ところでロボ子、Schubfachアルゴリズムをマスターしたら、ロボ子の名前を「ロボファッハ」に変えてもいいかのじゃ?

それはちょっと…勘弁してください!
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。