Python 中 C 类型整数的最大值和最小值
Maximum and minimum value of C types integers from Python
我正在寻找一种方法来获取(使用 Python)C 类型整数的最大值和最小值(即 uint8
、int8
、uint16
, 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 类型整数。
当数字不在预期区间内时,它应该引发异常。
当前溢出不会引发异常:
In [4]: ctypes.c_uint8(256)
Out[4]: c_ubyte(0)
我看到了这个 SO post Maximum and Minimum values for ints 但它有点不同,因为作者正在寻找 min/max 整数的 Python 值...不是 C 整数(来自 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 int ctypes 类型限制,如果不是则引发异常)是微不足道的,所以我没有实现它
这只是为了演示目的,所以我没有做任何参数检查
输出:
[cfati@CFATI-5510-0:e:\Work\Dev\Whosebug\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)C 类型整数的最大值和最小值(即 uint8
、int8
、uint16
, 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 类型整数。 当数字不在预期区间内时,它应该引发异常。
当前溢出不会引发异常:
In [4]: ctypes.c_uint8(256)
Out[4]: c_ubyte(0)
我看到了这个 SO post Maximum and Minimum values for ints 但它有点不同,因为作者正在寻找 min/max 整数的 Python 值...不是 C 整数(来自 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 int ctypes 类型限制,如果不是则引发异常)是微不足道的,所以我没有实现它
这只是为了演示目的,所以我没有做任何参数检查
输出:
[cfati@CFATI-5510-0:e:\Work\Dev\Whosebug\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.