Python:如何从 4 字节字节数组中获取 4 字节大小的整数?
Posted
技术标签:
【中文标题】Python:如何从 4 字节字节数组中获取 4 字节大小的整数?【英文标题】:Python: how to get a 4-byte sized integer from a 4-byte byte array? 【发布时间】:2015-11-05 22:45:47 【问题描述】:这是我编写的简单 Python(3.4 版)代码,用于从 4 个字节的数组中获取 32 位大小的整数(我假设为 int 类型):
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 位大小的整数)吗?
【问题讨论】:
sys.getsizeof()
包括 python 对象的开销...您可以使用 numpy 创建一个实际的 4 字节整数数组...或者只处理 4 字节数字的事实数据和 12 字节的 python 对象开销(这几乎肯定没问题......)它没有给你你期望的数字的实际值吗?如果不是,你期望什么与你得到什么?
此代码嗅探来自另一个 python 程序,我在其中使用 numpy 创建了 4 字节 int 数组。我想要做的是这样的(在 C 中): float f = 1.005;无符号整数 a = *(无符号整数 *)(&f);但是,python 抱怨 numpy 32bit int 无法容纳来自上面代码嗅探的 int。
capital I is unsigned 4 byte int ...如果你想要负值,你需要小写i(我认为)
如果您想获得 32 位浮点数,为什么不要求 struct
给您其中之一呢?
convert a string of bytes into an int (python)的可能重复
【参考方案1】:
首先,由于 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 库的问题/愚蠢的浮点精度错误,因为 Python 中的 log(n, x)
被翻译成 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))
其他功能同理。
我希望这对你有所启发!
【讨论】:
这很有趣,math.log(2**33, 2)
在 Python 2.7.5 中对我来说很好,返回 33.0
。
@MarkRansom:试试math.log(2**48-1, 2)
。只要 x
是 2 的完美幂,该函数就会起作用,但如果 x >= pow(2, 48) - 1
则不然。 编辑:对不起,我最初说障碍在2^32
,而它在2^48
。
@KemyLand:请注意 Python 3 的 math
module offers a log2
function 计算更准确。对于计算保存值所需的位,它在int
s 上提供了更有用/更高效的bit_length()
方法。由于 OP 使用的是 Python 3.4,因此您可以使用 x.bit_length()
来提高速度和准确性。
@ShadowRanger:谢谢,我没有注意到 OP 使用的是 3.4,所以我将保留 2.x 读者的代码原样并为 3.4 添加修改/优化的版本。
以上是关于Python:如何从 4 字节字节数组中获取 4 字节大小的整数?的主要内容,如果未能解决你的问题,请参考以下文章