Pythonで小数を16進数に変換する
Pythonでは、倍精度浮動小数点型により64ビットを使い小数点に関する演算をしています。この64ビットがコンピュータ上どのように記録されるかを知りたいと考えこれまでプログラムを作ってきました。これらのプログラムが正しく計算できているかを確認するため、Structモジュールを使い、正しい計算結果を出力します。Structモジュールを使うと、Pythonのデータがどのように扱われているかビット単位でみることができます。
struckモジュールのpack関数、unpack関数で小数のデータ形式を表示する
- from struct import pack, unpack
- frac=0.1
- print(pack('>d',frac))
- print(unpack('>Q', pack('>d', frac))[0])
- print(hex(unpack('>Q', pack('>d', frac))[0]))
- print(format(unpack('>Q', pack('>d', frac))[0],'064b'))
b'?\xb9\x99\x99\x99\x99\x99\x9a' 4591870180066957722 0x3fb999999999999a 0011111110111001100110011001100110011001100110011001100110011010
3. 浮動小数点として定義した変数にpack関数を適用することにより、その変数のbyte型(コンピュータの中でどのように取り扱われているか)を調べることができます。ただし、計算結果はxのprefixとともに16進数で表示されるはずが、先頭部が?になってしまい、すべての桁が表示されません。なお、引数’<d’の’<’はビッグエイディアンの意味です。IntelのCPUが入ったパソコンは、リトルエンディアンに設定されていて、逆向きに出力されてしまいます。また、’d’はdouble(倍精度浮動小数点)を指します。
4. 3.のデータをunpack関数でbyte型の変数を10進数に変換します。このときに10進数は2進数64ビットを10進数にした値となります。
5. 10進数にした値にhex関数を適用します。hex関数は10進数を16進数に変換します。
6. 16進数にした値のformat関数を適用し、2進数に変換します。出力するときの書式を’064b’は64ビットで出力することを示し、さらに0が付くことで64ビットに満たないときは文字列の先頭の方に不足分の’0’を補ってくれます。
浮動小数点を16進数の浮動小数点数の 16 進文字列表現
- print(0.1.hex())
- print(hex(10))
0x1.999999999999ap-4 0xa