2016-12-09 19 views
0

私は「個人」(モジュールや関数を使用せずにstruct、float ....、int ....など)を記述しようとしています。 Wikipediaによれば、STLバイナリファイルリーダ:バイナリSTLファイルが含ま:STRUCTを使用せずにバイトを浮動小数点数に変換する

  • 一般に無視される80文字(バイト)headern。

  • ファイル内の三角形ファセットの数を示す4バイトの符号なし整数。

  • 各三角形は、STLのASCIIバージョンの場合と同様に、各頂点のX/Y/Z座標の12個の32ビット浮動小数点数によって記述されます。これらの後に、属性バイト数である2バイト( "短い")の符号なし整数が続きます。標準形式では、ほとんどのソフトウェアが他のものを理解できないため、これはゼロになります。 (((3 + 3 + 3)+3)*各点の4 + 2 = 50バイト)

--Floating小数点数は、IEEE浮動小数点数として表現されると少しであると仮定されます私が保存されているか符号なし整数発見2人の救世主の助けを借りて

-endian--、私は3つの方法(手で計算)でファイルに三角形のファセットの数を把握することができます:

def int_from_bytes(inbytes): # ShadowRanger's 
    res = 0 
    for i, b in enumerate(inbytes): 
     res |= b << (i * 8) 
    return res 

または

def int_from_bytes(inbytes): # ShadowRanger's 
    res = 0 
    for b in inbytes: 
     res <<= 8 # Adjust bytes seen so far to make room for new byte 
     res |= b # Mask in new byte 
    return res 
今私は(リスト内の3番目の項目)ファイルの残りの部分を変換する必要が

または

def unsigned_int(s): # Robᵩ's 
    result = 0 
    for ch in s[::-1]: 
     result *= 256 
     result += ch 
    return result 

:浮動小数点数

最初のポイントのための50バイトは、次のとおりです。

b'\x9a'b'\xa3' b'\x14' b'\xbe' b'\x05' b'$' b'\x85' b'\xbe' b'N' b'b' 
b't' b'?' b'\xcd' b'\xa6' b'\x04' b'\xc4' b'\xfb' b';' b'\xd4' b'\xc1' 
b'\x84' b'w' b'\x81' b'A' b'\xcd' b'\xa6' b'\x04' b'\xc4' b'\xa5' b'\x15' 
b'\xd3' b'\xc1' b'\xb2' b'\xc7' b'\x81' b'A' b'\xef' b'\xa6' b'\x04' 
b'\xc4' b'\x81' b'\x14' b'\xd3' b'\xc1' b'Y' b'\xc7' b'\x81' b'A' b'\x00' 
b'\x00' 

私は手でこれを変換できますか?表現の原則は何ですか、私は手で変換を行うためにどのようなルールを知っていますか(いくつかのバイトは\ xで始まらない)。 ?

ありがとうございます。このよう

+0

使用しているPythonのバージョンは? – martineau

+0

これに実際の目的はありますか、それともあなたが得ることができるかを見極めようとしていますか? –

+0

また**なぜあなたは 'struct'モジュールを使用しないようにしようとしていますか? – martineau

答えて

1

def int_from_bytes(inbytes): 
    res = 0 
    shft = 0 
    for b in inbytes: 
     res |= ord(b) << shft 
     shft += 8 
    return res 

def float_from_bytes(inbytes): 
    bits = int_from_bytes(inbytes) 
    mantissa = ((bits&8388607)/8388608.0) 
    exponent = (bits>>23)&255 
    sign = 1.0 if bits>>31 ==0 else -1.0 
    if exponent != 0: 
     mantissa+=1.0 
    elif mantissa==0.0: 
     return sign*0.0 
    return sign*pow(2.0,exponent-127)*mantissa 


print float_from_bytes('\x9a\xa3\x14\xbe') 
print float_from_bytes('\x00\x00\x00\x40') 
print float_from_bytes('\x00\x00\xC0\xbf') 

出力:

-0.145155340433 
2.0 
-1.5 

フォーマットは浮動小数点IEEE-754です。これを試して、各ビットの意味を確認してください:https://www.h-schmidt.net/FloatConverter/IEEE754.html

+0

これは非正規化数または非有限数を扱わないことに注意する必要がありますが、これらはすべて珍しいケースですので、そうしたサポートなしでうまくいくかもしれません。 –

+0

@DietrichEpp oh yeah - 非正規表現を扱うように修正されました。 –

+0

私は小数点の代わりに魔法の定数のために16進数を使用します。しかし、悪い質問への良い答えを与えることをお祝いします。 –

関連する問題