2016-03-28 9 views
0

私は、sint32_tのような逆順のデータを "c-type"で埋めているbytearrayを持っていますが、sint24_tもあります。 24ビットの符号付き値は整数に変換する必要があります。 Pythonは負の値をマイナス記号の値として扱い、cは符号ビットを使って負の値を示します。bytearrayを別々の値に変換するためのより速く、より良い方法

だから私は、最初の32ビットに変更する思い付いた:

raw = bytearray('\x89\x00\x23') 
val = (ord(raw[0:1]) | (ord(raw[1:2])<<8) | (ord(raw[2:3])<<16)) 
if ((val & 0x00800000L) > 0): 
    val |= 0xFF000000L 

これは、今私は、32ビット符号付きの値を持っているが動作します。私はまだPythonで負の値になる必要があります。だから私は思いついた:

import ctypes 
p_val = ctypes.c_int32(val).value 

これは正しい方法でそれを変換します。 私は、これがもう少し効率的で速くなるようにしたいと思います。はるかに速い何かでこれを書き換える方法はありますか?私は反復ごとにこのように7つの値を作成する必要があります。私は "memoryview"について何か読んでいますか?

誰でも?

+0

2の補数の符号付き値がctypesのを必要としないの取得。バイトからの変換は 'struct'モジュールで実装することができますが、バッファを符号拡張して4バイトにする必要があります。例: 'val = struct.unpack( ' 127 else raw + b '\ x00')[0]'。 Python 2では、これは 'raw 'が' bytearray'であることに依存します。インデックス付けでは整数のバイト値が返されます。 Python 3では、この変換をより簡単に 'val = int.from_bytes(raw、 'little'、signed = True)'として実装することができます。 – eryksun

答えて

0

さまざまなオプション:

import struct 

MAX_INT24 = (1<<23)-1 
BIAS_INT24 = (1<<24) 

def int24(raw): 
    val = raw[0] | (raw[1] << 8) | (raw[2] << 16) 
    # val = struct.unpack('<i',raw + b'\x00')[0] # Another option 
    return val if val <= MAX_INT24 else val - BIAS_INT24 

raws = [b'\xff\xff\x7f', 
     b'\xff\xff\xff', 
     b'\xfe\xff\xff'] 

for raw in raws: 
    print(int24(raw)) 
    print(int.from_bytes(raw,'little',signed=True)) # Python 3 only 

出力:

8388607 
8388607 
-1 
-1 
-2 
-2 
+0

ありがとう、分で学ぶ... :-) – Roland

関連する問題