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

标签 python integer max size ctypes

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

我希望在 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 在这方面有很好的功能:

julia> typemax(UInt8)
0xff

julia> typemin(UInt8)
0x00

julia> typemin(Int8)
-128

julia> typemax(Int8)
127

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

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

目前溢出不会引发异常:

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

我看到了这个 SO 帖子 Maximum and Minimum values for ints但它有点不同,因为作者正在寻找 Python 整数的最小/最大值......而不是 C 整数(来自 Python)

我还注意到 Detecting C types limits ("limits.h") in python?但是,即使它非常相关,也不能真正回答我的问题。

最佳答案

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

Integers have unlimited precision.

翻译成代码:

>>> 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没有提及任何关于类型限制的内容(请注意,有些东西没有记录在那里),让我们手动找出它们。

code00.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(*argv):
    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} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
                                                   64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    rc = main(*sys.argv[1:])
    print("\nDone.")
    sys.exit(rc)

注意事项:

  • 代码依赖于这样一个事实:对于某个整数类型,它的区间(并且限制是区间的端点)是:

    • 签名 (2的补码):[- (2 bit_size - 1), 2 bit_size - 1 - 1]

    • 无符号:[0, 2 bit_size - 1]

  • 要检查 a 类型的 signum,请使用 -1(会自动转换为上限(由于环绕算术)由无符号类型)

  • 输出有很多重复(如下),因为有些类型只是其他类型的“别名”

  • 剩下的任务(创建一个比较 Python intCTypes 类型限制的函数,并引发一个如果不是则异常)是微不足道的,所以我没有实现它

  • 这只是为了演示目的,所以我没有做任何参数检查

输出:

  • :

    • Python pc064 (064bit):

      [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q052475749]> "e:\Work\Dev\VEnvs\py_pc064_03.09_test0\Scripts\python.exe" ./code00.py
      Python 3.9.9 (tags/v3.9.9:ccb0e6a, Nov 15 2021, 18:08:50) [MSC v.1929 64 bit (AMD64)] 064bit 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)
      
      Done.
      
    • Python pc032 (032bit):

      [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q052475749]> "e:\Work\Dev\VEnvs\py_pc032_03.10_test0\Scripts\python.exe" ./code00.py
      Python 3.10.1 (tags/v3.10.1:2cd268a, Dec  6 2021, 18:54:59) [MSC v.1929 32 bit (Intel)] 032bit 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)
      
      Done.
      
  • Nix (Linux - WSL2) - Python pc064 :

    (qaic-env) [cfati@cfati-5510-0:/mnt/e/Work/Dev/StackOverflow/q052475749]> python ./code00.py
    Python 3.8.10 (default, Mar 15 2022, 12:22:08) [GCC 9.4.0] 064bit on linux
    
    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_int limits: (-2147483648, 2147483647)
    c_uint limits: (0, 4294967295)
    c_int limits: (-2147483648, 2147483647)
    c_uint limits: (0, 4294967295)
    c_long limits: (-9223372036854775808, 9223372036854775807)
    c_ulong limits: (0, 18446744073709551615)
    c_long limits: (-9223372036854775808, 9223372036854775807)
    c_ulong limits: (0, 18446744073709551615)
    c_long limits: (-9223372036854775808, 9223372036854775807)
    c_ulong limits: (0, 18446744073709551615)
    
    Done.
    

关于python - Python中C类型整数的最大值和最小值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52475749/

相关文章:

python - 在值重复的情况下在字典中查找最大键的最大值的键

python - 如何在 Python 中的图像上打印印地语句子(unicode)?

python - Python中Stata宏的等价物

r - 如何在运行时向用户询问一个整数,如果没有得到则再次递归询问?

java - 字符串到 Integer 和 int 的转换

python - 希望加快这个最大成对产品

python - 为什么 < 不能从命令行(简单的 Python 代码)读取文件?

python - 如何在 Python 中提取 <h1></h1> 之间的文本?

将 2 个字节的字符串(文本)表示形式转换为整数

MySQL查询仅显示每列的最大值长度