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() 不会返回 length 的 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 &gt;= 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 &gt;= pow(2, 48) - 1 则不然。 编辑:对不起,我最初说障碍在2^32,而它在2^48 @KemyLand:请注意 Python 3 的 math module offers a log2 function 计算更准确。对于计算保存值所需的位,它在ints 上提供了更有用/更高效的bit_length() 方法。由于 OP 使用的是 Python 3.4,因此您可以使用 x.bit_length() 来提高速度和准确性。 @ShadowRanger:谢谢,我没有注意到 OP 使用的是 3.4,所以我将保留 2.x 读者的代码原样并为 3.4 添加修改/优化的版本。

以上是关于Python:如何从 4 字节字节数组中获取 4 字节大小的整数?的主要内容,如果未能解决你的问题,请参考以下文章

使用校验和将字节数组转换为字符串。在 python 中重新迭代时获取额外的空字节

如何在java中将4字节数组转换为浮点数

如何从 Python 3 中的字节数组中的特定位中提取值?

如何从字节数组中获取正确的温度值

用于串行通信的 Python 字节数组

如何在C ++中将字节数组中的整数转换为数字