将结构格式字符串转换为允许的 int 值范围
Converting struct format string to range of allowable int values
Python struct
库有一堆与 ctype 对应的格式字符串 ("h"
: int16
, "H"
: uint16
).
有没有一种简单的方法可以从格式字符串(例如 "h"
、"H"
等)到可能值的范围(例如 -32768 到 32767、0 到 65535、等等)?
我看到 struct
库提供了 calcsize
,但我真正想要的是 calcrange
.
是否有内置解决方案,或者我忽略的优雅解决方案?我也对第三方图书馆开放。
我在下面做了一个 DIY calcrange
,但它只涵盖了有限数量的可能格式字符串,并做了一些不可概括的假设。
def calcrange(fmt: str) -> Tuple[int, int]:
"""Calculate the min and max possible value of a given struct format string."""
size: int = calcsize(fmt)
unsigned_max = int("0x" + "FF" * size, 16)
if fmt.islower():
# Signed case
min_ = -1 * int("0x80" + "00" * (calcsize(fmt) - 1), 16)
return min_, unsigned_max + min_
# Unsigned case
return 0, unsigned_max
数学可以简化。如果 b
是位宽,则无符号值为 0 到 2b-1,有符号值为 -2(b-1) 到 2(b-1)-1。它仅适用于整数类型。
这是一个简化版本:
from typing import *
import struct
def calcrange(intcode):
b = struct.calcsize(intcode) * 8
if intcode.islower():
return -2**(b-1),2**(b-1)-1
else:
return 0,2**b-1
for code in 'bBhHiIlLqQnN':
s,e = calcrange(code)
print(f'{code} {s:26,} to {e:26,}')
输出:
b -128 to 127
B 0 to 255
h -32,768 to 32,767
H 0 to 65,535
i -2,147,483,648 to 2,147,483,647
I 0 to 4,294,967,295
l -2,147,483,648 to 2,147,483,647
L 0 to 4,294,967,295
q -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
Q 0 to 18,446,744,073,709,551,615
n -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
N 0 to 18,446,744,073,709,551,615
Python struct
库有一堆与 ctype 对应的格式字符串 ("h"
: int16
, "H"
: uint16
).
有没有一种简单的方法可以从格式字符串(例如 "h"
、"H"
等)到可能值的范围(例如 -32768 到 32767、0 到 65535、等等)?
我看到 struct
库提供了 calcsize
,但我真正想要的是 calcrange
.
是否有内置解决方案,或者我忽略的优雅解决方案?我也对第三方图书馆开放。
我在下面做了一个 DIY calcrange
,但它只涵盖了有限数量的可能格式字符串,并做了一些不可概括的假设。
def calcrange(fmt: str) -> Tuple[int, int]:
"""Calculate the min and max possible value of a given struct format string."""
size: int = calcsize(fmt)
unsigned_max = int("0x" + "FF" * size, 16)
if fmt.islower():
# Signed case
min_ = -1 * int("0x80" + "00" * (calcsize(fmt) - 1), 16)
return min_, unsigned_max + min_
# Unsigned case
return 0, unsigned_max
数学可以简化。如果 b
是位宽,则无符号值为 0 到 2b-1,有符号值为 -2(b-1) 到 2(b-1)-1。它仅适用于整数类型。
这是一个简化版本:
from typing import *
import struct
def calcrange(intcode):
b = struct.calcsize(intcode) * 8
if intcode.islower():
return -2**(b-1),2**(b-1)-1
else:
return 0,2**b-1
for code in 'bBhHiIlLqQnN':
s,e = calcrange(code)
print(f'{code} {s:26,} to {e:26,}')
输出:
b -128 to 127
B 0 to 255
h -32,768 to 32,767
H 0 to 65,535
i -2,147,483,648 to 2,147,483,647
I 0 to 4,294,967,295
l -2,147,483,648 to 2,147,483,647
L 0 to 4,294,967,295
q -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
Q 0 to 18,446,744,073,709,551,615
n -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
N 0 to 18,446,744,073,709,551,615