プログラミング
浮動小数点数をバイナリで表示する
Printing floating point numbers in binary (johndcook.com)
要約
この記事では、浮動小数点数をバイナリ(2進数)で表現する方法について解説しています。Pythonのfloat型には直接的なバイナリ変換関数がないため、まず16進数表現からバイナリに変換し、その後指数部分を考慮して最終的なバイナリ形式を得る手順を示しています。
全文翻訳
整数の16進数(ヘキサデシマル)表現を、各桁を2進数に変換するだけで2進数表現に変換できることはよく知られています。例えば、CAFEhex は 1100 1010 1111 1110two です。浮動小数点数でも同じことができるというのは、おそらくあまり知られていないでしょう。Pythonで浮動小数点数のバイナリ表現を見つける方法を探していましたが、それを行う関数がないことがわかりました。しかし、float型には16進数表現を表示するメソッドがあります。例えば、πの16進数表現は次のようになります。
>>> import math
>>> (math.pi).hex()
'0x1.921fb54442d18p+1'
興味深いことに、末尾のp+kの部分は16のべき乗ではなく2のべき乗です。したがって、1.921fb54442d18hexを2進数に変換した後、2を掛ける、つまり小数点を右に1つ移動させる必要があります。まず、1.921fb54442d18hexを、1、9、2などの各桁を2進数に変換することによって2進数に変換します。
1.1001 0010 0001 1111 1011 0101 0100 0100 0100 0010 1101 0001 1000two
その後、p+1の部分を考慮して小数点をシフトすると、π = 11.001001000011111101101010100010001000010110100011000two となります。
小数部分を整数と解釈して、Pythonのbin()関数を使用して16進数に変換できますが、0ビットでパディングする必要があるかもしれません。例えば、
>>> (1.03).hex()
'0x1.07ae147ae147bp+0'
>>> bin(0x7ae147ae147)
'0b1111010111000010100011110101110000101000111'
1.03ten の2進数表現は 1.000001111010111000010100011110101110000101000111two です。
合計5つのゼロビットを追加しました。小数点の後の0のために4ビット、7を0111twoに変換するために1ビットです。
Brian Oxley 2026年7月27日 14:09
これは興味深いですね。C標準ライブラリは論理的な表現ではなく内部的な表現を示しており、printfファミリーで適切なフォーマットは見つかりませんでした。強力なPerlでさえ中間ステップが必要です。確認したところ、明白なワンステップの解決策やprintfフォーマットフラグはないようです。ビッグエンディアンに強制することで、より良い結果が得られるかもしれません。https://float.exposed/で確認するのは興味深いです。試すべき例としては、エンディアンを壊すもの、隠されたビット、バイアスされた指数、フォーマットの癖などがあります。私はこの分野の専門家ではありません。いくつかの例を試しました。