

コンピューター初心者です。  
Pythonで、IEEE単精度実数形式を10進数へ変換するプログラムコードが欲しいのですが  
（例えば、00111110011000101000111101011100 を  
⇒ 0.2212499976158142 と変換したい）

参考となるコードやモジュールなどありますでしょうか？  
教えて下さい。


CC BY-SA 4.0
2018-07-23T09:30:40.320
46870
2018-07-24T04:18:45.660
29424
question
python
IEEE単精度実数形式から10進数への変換


IEEE単精度実数形式の定義に従えば、文字列で表示されている場合、符号ビット: 1ビット、指数部の幅: 8ビット、仮数部の幅:
23ビットとなっているので、次のように計算できます。ただし指数部が、`00000000`と`11111111`の場合は除きます。（参考 Wikipedia
[単精度浮動小数点数](https://ja.wikipedia.org/wiki/%E5%8D%98%E7%B2%BE%E5%BA%A6%E6%B5%AE%E5%8B%95%E5%B0%8F%E6%95%B0%E7%82%B9%E6%95%B0)）

[code]

    s = '00111110011000101000111101011100'
    (-1)**int(s[0:1],2) * int('1'+s[9:],2)/2**23 * 2**(int(s[1:9],2)-127)
    
[/code]

現実には、コメントにあるようにバイト列に変換して`struct`パッケージを使うのが便利です。

[code]

    import struct
    s = '00111110011000101000111101011100'
    struct.unpack('f', int(s,2).to_bytes(4,'little'))[0]
    
[/code]

`struct`パッケージを使う場合、自動的にバイト列に変換されるので意識することはあまりないかもしれませんが、直接メモリーやバイナリーファイルを扱うときや他のマシンとのバイナリーファイルを交換する場合には、エンディアンのことも知っておいた方がいいと思います。普通のPCで`struct.pack`を使ってバイト列に変換すると以下のようになっていると思います。

[code]

    >>> struct.pack('i', 0b00111110011000101000111101011100)
    b'\\\x8fb>'
    >>> import binascii
    >>> binascii.hexlify(struct.pack('i', 0b00111110011000101000111101011100))
    b'5c8f623e'
    
[/code]

今回の質問にある`00111110011000101000111101011100`は`Ox3e628f5c`なので逆順になっています。単精度実数形式のように1バイトよりも大きいものを扱う時にどのような順番で並べるか（バイトオーダー）に2種類の方式があって、`b'\x5c\x8f\x62\x3e'と下位側から並べるのを「リトルエンディアン」と呼びます。上位側から`b'\x3e\x62\x8f\x5c'`に並べるのを「ビッグエンディアン」と呼びます。IntelのCPUはリトルエンディアンを採用しているので、上のようになります。


CC BY-SA 4.0
2018-07-24T02:17:00.250
46887
2018-07-24T04:18:45.660
2018-07-24T04:18:45.660
15171
15171
46870
answer