2016-05-04 10 views
0

私は、Pythonがバイトを浮動小数点に変換する方法を詳細に理解したいと思います。だからpython3がバイトを浮動小数点に変換する方法は?

~> python3.5 23.py 
Bytes = b'\x00\x00\xb8A' 
Float = (23.0,) 

~> cat 23.py 
import struct 
f='23.b'            
fd=open(f,'rb')          # Open the file 
value_bytes=fd.read()        # Read file, 4 bytes in total 
                # Output: 
print("Bytes =",value_bytes)       # Bytes = b'\x00\x00\xb8A' 
print("Float =",struct.unpack("<f",value_bytes))  # Float = (23.0,) 

がコードを実行します。

~> echo 23 > 23.a 
~> a2b < 23.a n1=1 > 23.b 

がのが今のpython3コード23.pyを書いてみましょう:
はちょうど1フロート23.0を含むバイナリファイルを作成してみましょう。私はPythonがバイト '\ x00 \ x00 \ xb8A'を浮動小数点型23.0に変換する方法を知りたいですか?これはDEC-BIN-HEX-ASCII表現と関係がありますが、私はすでにこれを理解しようとしている私の脳を壊しました。

DEC = 23 
BIN = 0000 0000 0001 0111 
HEX = 0 0 1 7 

「\ x00 \ x00 \ xb8A」はどのように取得しますか?逆に、 '\ x00 \ x00 \ xb8A'はどのように23.0に変換されますか?
誰も私をステップバイステップで説明できますか?ありがとう。

+2

'a2b'コマンドは何をしますか?私のDebian、CentOS、またはOS Xシステムには、そのコマンドがありません。 –

+0

@Martijnそうです、私はそれを見落としました。それは「地震学Unix」の一部です。 asciiは行ごとに浮動小数点数を読み込み、2進数に変換します。リトルエンディアンは、この場合、私は信じています。 – Michael

+0

そうです、[this tool](http://www.cwp.mines.edu/sututor/node33.html)ですか? –

答えて

3

これは明らかdocumented in the format tableある:

'f''d'変換コードについて

、パックされた表現にかかわらず、浮動小数点形式の、('f'用)IEEE 754 binary32又はbinary64('d'ための)フォーマットを使用しますプラットフォームによって使用されます。

この形式を理解するには、IEEE floating point standardを参照してください。 fコードを使用したので、binary32, or single precision formatを探してください。

このフォーマットは32ビットに分割からなる:

  • 符号ビット:1ビット
  • 指数幅:8ビット
  • 仮数精度:24ビット(23明示的に格納されている)

バイナリデータをビットで見ると(リトルエンディアンとして扱われるので、これを逆にしてWikipediaのビッグエンディアンの順序に合わせます):

>>> ('{:08b}' * 4).format(*b'\x00\x00\xb8A'[::-1]) 
'01000001101110000000000000000000' 

符号が0、指数幅が131(2の補数で127が4になる)、仮数の精度または仮数が1.4375(1 + 1/4 + 1/8 + 1/16、各バイナリ分数は有効ビットです)。全整数とバイナリで小数点以下の値を表現する、

>>> 1 * 2 ** 4 * 1.4375 (sign, positive, times 2 to the power exponent, times fractions) 
23.0 

は他の方法に行く;一緒

>>> ('{:08b}' * 4).format(*b'\x00\x00\xb8A'[::-1])[:1] # sign 
'0' 
>>> ('{:08b}' * 4).format(*b'\x00\x00\xb8A'[::-1])[1:9] # exponent, signed 
'10000011' 
>>> int(('{:08b}' * 4).format(*b'\x00\x00\xb8A'[::-1])[1:9], 2) - 127 # exponent, signed 
4 
>>> ('{:08b}' * 4).format(*b'\x00\x00\xb8A'[::-1])[9:] # mantissa 
'01110000000000000000000' 
>>> # That's the 1/4 bit plus the 1/8th bit plus the 1/16th bits all enabled. 
... 
>>> 1 + 1/4 + 1/8 + 1/16 
1.4375 

これらは、実際の浮動小数点値を形成しますおおよそバイナリ分数はすべての可能な実数を表すことができないので、非整数部分を持つ必要があります。 23。それがここに簡単ですが、我々は唯一のバイナリに整数成分を変換する必要がありますので0、何の非整数成分を持っていない:

>>> format(23, 'b') 
'10111' 

ので、実数のバイナリ表現が10111.0です。小数点を上下に移動して1と小数点を取得します。ここで小数点を4点上に移動して1.0111にする必要があります。これにより、指数(4)、および有意な(0111と未使用の分数のための19のゼロ)が得られます。値が正であるので、あなたは、符号付きの値として指数が(127 == 131を追加バイナリ== 10000011に131をコード)、および追加0などの記号をコード重要:

0 10000011 01110000000000000000000 

はにそれをチョッピング8ビット(4バイト)の4つのグループはあなたに0x41 0xB8 0x00 0x00を与えます。バイトのためのPythonのrepr()出力はあなたのバイト、可能な場合のための印刷可能なASCII文字を与え、0x41はASCIIテーブル内の文字A次のとおりです。

>>> bytes([0b01000001, 0b10111000, 0b00000000, 0b00000000]) 
b'A\xb8\x00\x00' 
リトルエンディアン表現のため、これらのバイトを逆

>>> bytes([0b01000001, 0b10111000, 0b00000000, 0b00000000])[::-1] 
b'\x00\x00\xb8A' 

IEEE binary32形式がthis online converterでどのように動作するかを視覚化することができます。

+0

OK、ありがとうございます。 32バイナリをIEEE浮動小数点に変換する方法は明らかです。しかし、私はまだ紛失しています。どのようにしてb '\ x00 \ x00 \ xb8A'から '01000001101110000000000000000000'を得、23からb '\ x00 \ x00 \ xb8A'を得るのですか。 – Michael

+0

@Michael: 'b '\ x00 \ x00 \ xb8A'可能な場合はASCIIで表示されます(ASCII 65は ''A' ')4バイトを表し、0,0,184、および65の値を10進数で表します。これらのバイトを最初に反転(リトルエンディアンからビッグエンディアンに)し、それらをバイナリ表現に変換すると01000001 10111000 00000000 00000000となります。 –

+0

@Michael:23.0からバイナリ表現への移行については、[* 10進表現からバイナリフォーマットへ* (https://///。 '23.0'はバイナリで' 10111.0'(2進数で)ですが、その値は4ステップ右から1.0111にシフトすることによって '正規化'されます。そのようにすれば、指数として '4 'を、仮数として' 0111'だけをエンコードする必要があります。 –

関連する問題