将结构格式字符串转换为允许的 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