在 python 中,当使用 pack 时,它会在打包 long 变量时截断我的 MSB 位,
In python while using pack it is truncating my MSB bits while packing a long variable,
int1 = 11111111
int2 = 22222222
long1 = 6666666666666666
int3 = 33333333
int4 = 44444444
int5 = 55555555
pack_list = (int1,int2,long1,int3,int4,int5)
pack_format = struct.Struct('> I I L I I I')
pack_data = pack_format.pack(*pack_list)
print "Original_values:", pack_list
print "Format_string:", pack_format.format
print "Uses:", pack_format.size,'bytes'
print "Packed_value:", binascii.hexlify(pack_data)
我在一个 long 变量中有 64 位,但是当我使用 big-endian 打包时,它会将其视为一个整数,您可以在输出中看到它显示为 24 字节而不是 28 字节,这是数据。谁能告诉我发生了什么事并帮助我获得大端打包数据中的所有 64 位
Original Values: (11111111, 22222222, 66666666, 33333333, 44444444, 55555555)
Format_string: > I I L I I I
Uses: 24 bytes
Packed_value: 111111112222222266666666333333334444444455555555
格式说明符L
表示Clong
,一般为32位——与Cint
大小相同。所以你的 64 位数字太大,放不下。 (我很确定 Python 2.7 和 3.x 应该给你一个 OverflowError 或 ValueError 之类的东西,而不是默默地截断......但无论如何,它不会起作用。)
格式说明符Q
表示一个Clong long
,一般是64位,你要的就是这个
如果你想知道为什么 Python 有 I 和 L,当它们表示相同的东西时——好吧,这真的只是因为 C 有 int 和 long,但是有,或者至少使用过是,这是一个原因。如今,int 几乎总是 32 位,但在最初编写 Python 时,它通常是 16 位或 32 位中在您的平台上更快的那个。所以,如果你试图匹配来自某些定义为使用 int 的 Unix API 的结构,你必须使用 I;定义为使用 long 的结构,您必须使用 L;将它们混合在一起,您的代码将无法在不同系统之间移植。
如果您想知道为什么 q
是 long long
的缩写——它确实是“quad”的缩写,至少是间接的。最有可能的是,它来自各种不同的 Unix 系统,它们使用 q
作为其非标准 64 位类型的 printf
格式说明符前缀(因此 %qd
表示 64 位 int 打印为十进制数)。如果不是,它可能来自 Windows 对两个 32 位整数的 64 位结构使用 QWORD
。在这两种情况下,“q”表示“quad”——16 位是一个字,32 位是一个双字,而 64 位是一个四(四)字。 (在 printf
的情况下,只有那么多的单字母前缀可以绕过也可能是相关的。后来,C 和 POSIX 标准通过只允许多字母前缀来解决这个问题,所以现在是 %lld
, 是 long long
的缩写。)
int1 = 11111111
int2 = 22222222
long1 = 6666666666666666
int3 = 33333333
int4 = 44444444
int5 = 55555555
pack_list = (int1,int2,long1,int3,int4,int5)
pack_format = struct.Struct('> I I L I I I')
pack_data = pack_format.pack(*pack_list)
print "Original_values:", pack_list
print "Format_string:", pack_format.format
print "Uses:", pack_format.size,'bytes'
print "Packed_value:", binascii.hexlify(pack_data)
我在一个 long 变量中有 64 位,但是当我使用 big-endian 打包时,它会将其视为一个整数,您可以在输出中看到它显示为 24 字节而不是 28 字节,这是数据。谁能告诉我发生了什么事并帮助我获得大端打包数据中的所有 64 位
Original Values: (11111111, 22222222, 66666666, 33333333, 44444444, 55555555) Format_string: > I I L I I I
Uses: 24 bytes
Packed_value: 111111112222222266666666333333334444444455555555
格式说明符L
表示Clong
,一般为32位——与Cint
大小相同。所以你的 64 位数字太大,放不下。 (我很确定 Python 2.7 和 3.x 应该给你一个 OverflowError 或 ValueError 之类的东西,而不是默默地截断......但无论如何,它不会起作用。)
格式说明符Q
表示一个Clong long
,一般是64位,你要的就是这个
如果你想知道为什么 Python 有 I 和 L,当它们表示相同的东西时——好吧,这真的只是因为 C 有 int 和 long,但是有,或者至少使用过是,这是一个原因。如今,int 几乎总是 32 位,但在最初编写 Python 时,它通常是 16 位或 32 位中在您的平台上更快的那个。所以,如果你试图匹配来自某些定义为使用 int 的 Unix API 的结构,你必须使用 I;定义为使用 long 的结构,您必须使用 L;将它们混合在一起,您的代码将无法在不同系统之间移植。
如果您想知道为什么 q
是 long long
的缩写——它确实是“quad”的缩写,至少是间接的。最有可能的是,它来自各种不同的 Unix 系统,它们使用 q
作为其非标准 64 位类型的 printf
格式说明符前缀(因此 %qd
表示 64 位 int 打印为十进制数)。如果不是,它可能来自 Windows 对两个 32 位整数的 64 位结构使用 QWORD
。在这两种情况下,“q”表示“quad”——16 位是一个字,32 位是一个双字,而 64 位是一个四(四)字。 (在 printf
的情况下,只有那么多的单字母前缀可以绕过也可能是相关的。后来,C 和 POSIX 标准通过只允许多字母前缀来解决这个问题,所以现在是 %lld
, 是 long long
的缩写。)