2015-11-05 107 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

相关问题