代码之家  ›  专栏  ›  技术社区  ›  scls

Python中C类型整数的最大值和最小值

  •  2
  • scls  · 技术社区  · 6 年前

    我正在寻找一种方法来获取(使用Python)C类型整数的最大值和最小值(即 uint8 , int8 , uint16 , int16 , uint32 int32 , uint64 , int64

    我本想在你家里找到这个的 ctypes 模块

    In [1]: import ctypes
    In [2]: ctypes.c_uint8(256)
    Out[2]: c_ubyte(0)
    In [3]: ctypes.c_uint8(-1)
    Out[3]: c_ubyte(255)
    

    朱莉娅有一个很好的特点:

    julia> typemax(UInt8)
    0xff
    
    julia> typemin(UInt8)
    0x00
    
    julia> typemin(Int8)
    -128
    
    julia> typemax(Int8)
    127
    

    我很肯定Python也有类似的东西。

    理想情况下,我甚至在寻找一种方法来确保给定的Python整数(据说是无界的)可以安全地转换为给定大小的C类型整数。 当数字不在预期的间隔内时,它应该引发异常。

    In [4]: ctypes.c_uint8(256)
    Out[4]: c_ubyte(0)
    

    我看到了这个帖子 Maximum and Minimum values for ints

    我也注意到了 Detecting C types limits ("limits.h") in python?

    1 回复  |  直到 6 年前
        1
  •  5
  •   CristiFati    4 年前

    根据: [Python 3.Docs]: Numeric Types - int, float, complex :

    整数有无限的精度。

    翻译成代码:

    >>> i = 10 ** 100
    >>> i
    10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    >>> len(str(i))
    101
    >>> i.bit_length()
    333
    

    另一方面,每个 C级 类型具有固定大小(取决于平台/体系结构),如中所示 [CppReference]: Fundamental types .

    [Python 3.Docs]: ctypes - A foreign function library for Python 没有提到任何类型限制( 请注意,这里没有记录一些内容 ),让我们手动查找。

    代码00.py

    #!/usr/bin/env python3
    
    import sys
    from ctypes import c_int8, c_uint8, c_byte, c_ubyte, c_int16, c_uint16, \
        c_int32, c_uint32, c_int, c_uint, c_long, c_ulong, c_longlong, c_ulonglong, \
        c_int64, c_uint64, \
        sizeof
    
    
    def limits(c_int_type):
        signed = c_int_type(-1).value < c_int_type(0).value
        bit_size = sizeof(c_int_type) * 8
        signed_limit = 2 ** (bit_size - 1)
        return (-signed_limit, signed_limit - 1) if signed else (0, 2 * signed_limit - 1)
    
    
    def main():
        test_types = [
            c_int8,
            c_uint8,
            c_byte,
            c_ubyte,
            c_int16,
            c_uint16,
            c_int32,
            c_uint32,
            c_int,
            c_uint,
            c_long,
            c_ulong,
            c_longlong,
            c_ulonglong,
            c_int64,
            c_uint64
        ]
        for test_type in test_types:
            print("{:s} limits: ({:d}, {:d})".format(test_type.__name__, *limits(test_type)))
    
    
    if __name__ == "__main__":
        print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
        main()
    

    笔记

    • 代码依赖于这样一个事实:对于某个整数类型,它的区间(限制是区间的端点)是:
      • ( 2 : [-(2 钻头尺寸-1 - 1]
      • 未签名 : [0, 2 - 1]
    • 检查a型的 符号 -1 (将自动转换为上限(由于 )由 未签名 类型)
    • 任务的其余部分(创建一个比较 蟒蛇 C类型
    • 这只是为了演示的目的,所以我没有做任何参数检查

    输出

    (py35x64_test) e:\Work\Dev\StackOverflow\q052475749>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" code00.py
    Python 3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32
    
    c_byte limits: (-128, 127)
    c_ubyte limits: (0, 255)
    c_byte limits: (-128, 127)
    c_ubyte limits: (0, 255)
    c_short limits: (-32768, 32767)
    c_ushort limits: (0, 65535)
    c_long limits: (-2147483648, 2147483647)
    c_ulong limits: (0, 4294967295)
    c_long limits: (-2147483648, 2147483647)
    c_ulong limits: (0, 4294967295)
    c_long limits: (-2147483648, 2147483647)
    c_ulong limits: (0, 4294967295)
    c_longlong limits: (-9223372036854775808, 9223372036854775807)
    c_ulonglong limits: (0, 18446744073709551615)
    c_longlong limits: (-9223372036854775808, 9223372036854775807)
    c_ulonglong limits: (0, 18446744073709551615)