【问题标题】:Converting struct format string to range of allowable int values将结构格式字符串转换为允许的 int 值范围
【发布时间】:2021-11-11 19:45:08
【问题描述】:

Pythonstruct库有一堆格式字符串对应一个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

【问题讨论】:

    标签: python struct ctypes


    【解决方案1】:

    数学可以简化。如果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
    

    【讨论】:

    • 是的,这更容易阅读,伟大的工作:) 这应该是库 imo 的一部分
    猜你喜欢
    • 1970-01-01
    • 2015-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多