2015-11-05 171 views
1

下面是一個簡單的Python(版本3.4)代碼我已經寫得到一個32位大小的整數(INT型我假設)從4個字節的數組:Python:如何從一個4字節的字節數組中獲取一個4字節大小的整數?

import binascii 
import socket 
import struct 
import array 
import pickle 
import ctypes 
import numpy 
import sys 

float_val = 1.0 + 0.005 
print(float_val) 

packed = struct.pack('f', float_val) 
print(len(packed)) 

tempint2 = struct.unpack(">I", packed)[0] 
tempint3 = struct.unpack_from(">I", packed)[0] 
tempint4 = int.from_bytes(packed, byteorder='big', signed=False) 

print(sys.getsizeof(tempint2)) 
print(tempint2) 
print(sys.getsizeof(tempint3)) 
print(tempint3) 
print(sys.getsizeof(tempint4)) 
print(tempint4) 

然而,沒有嘗試( tempint2/tempint3/tempint4)給出了我期望的值(4字節大小的整數)。不知何故,大小都是18個字節(sys.getsizeof()函數的結果)。你能告訴我如何得到預期的答案(4字節或32位大小的整數)?

+2

'sys.getsizeof()'包含python對象的開銷......你可以使用numpy來創建一個實際的4字節整數的數組......或者只是處理這個事實,即4個字節的數字數據和12個字節的python對象開銷(這幾乎肯定沒問題......)它是不是給了你期望的實際數值?如果不是你期望的是什麼,你會得到什麼? –

+0

此代碼sniffet來自另一個python程序,我使用numpy創建了4字節的int數組。我想要做的就是這樣(在C中):float f = 1.005; unsigned int a = *(unsigned int *)(&f);)然而,python抱怨numpy 32位int無法容納來自上面的代碼sniffet的int int –

+0

大寫字母I是無符號4字節int ...如果你想要負值將需要小寫我(我認爲) –

回答

0

首先,由於Python的...恩...「神奇」,sys.getsizeof()不會返回len GTH一個list,但sizeof整個數據結構由Python解釋器內部表示。現在

,答案(爲整數)簡直是......(對於Python 2.x的/ Python的3.x和32位/ 64位的所有組合):

from math import ceil, floor, log 

def minimumAmountOfBytesToHoldTheStuff(x): 
    # Avoid math domain errors 
    if x < 0: 
     x = ~x 

    # Avoid more math domain erros 
    if x == 0: 
     x = 1 

    return int(ceil((floor(log(x, 2)) + 1)/8)) 

def powersOfTwo(): 
    x = 1 
    while True: 
     yield x 
     x *= 2 

def minimumAmountOfBytesToHoldTheStuffOnRealMachines(x): 
    bytes = minimumAmountOfBytesToHoldTheStuff(x) 
    for power in powersOfTwo(): 
     if bytes <= power: 
      return power 

print(minimumAmountOfBytesToHoldTheStuffOnRealMachines(tempint)) 

:看起來log(x, 2)中斷了x >= pow(2, 48) - 1,整個算法也是如此。這可能是從C庫/愚蠢的浮點accurracy錯誤的問題,因爲在log(n, x) Python是在C.翻譯成log(n)/log(x)

編輯:這是一個爲Python 3.x的優化版,是獨立於機器人浮點運算和對數運算,因此在所有情況下都是準確的...

from math import ceil 

def minimumAmountOfBytesToHoldTheStuff(x): 
    # Avoid math domain errors 
    if x < 0: 
     x = ~x 

    # Avoid more math domain erros 
    if x == 0: 
     x = 1 

    return int(ceil(x.bit_length()/8)) 

其他功能是一樣的。

我希望這能帶給你一些亮點!

+0

這很有趣,'math.log(2 ** 33,2)'在Python 2.7.5中對我很好,返回'33.0'。 –

+0

@MarkRansom :試用'math.log(2 ** 48-1,2)' 'x'是2的完美冪,但如果'x> = pow(2,48) - 1'則不然。 **編輯**:對不起,我原本說屏障是在'2^32',而在'2^48'。 – 3442

+0

@KemyLand:請注意,Python 3的['math'模塊提供了一個'log2'函數](https://docs.python.org/3/library/math.html#math.log2),可以更準確地計算出來。並且爲了計算保存一個值所需的位,它在'int'上提供了更有用/有效的'bit_length()'方法。由於OP使用Python 3.4,因此速度和準確性可以使用'x.bit_length()'。 – ShadowRanger

相關問題