【问题标题】:How does Python manage int and long?Python如何管理int和long?
【发布时间】:2011-01-07 11:21:56
【问题描述】:

有人知道 Python 如何在内部管理 int 和 long 类型吗?

  • 它是否动态选择正确的类型?
  • int 的限制是多少?
  • 我使用的是 Python 2.6,与以前的版本有什么不同吗?

我应该如何理解下面的代码?

>>> print type(65535)
<type 'int'>
>>> print type(65536*65536)
<type 'long'>

更新:

>>> print type(0x7fffffff)
<type 'int'>
>>> print type(0x80000000)
<type 'long'>

【问题讨论】:

  • 在 CPython 中它们不只是动态映射到标准数据类型吗?
  • 是的,我认为是的。我还怀疑一切都在堆上分配,所以当一个数字需要更高的精度时,他们只需realloc 就可以了。但我不太确定,所以我将答案留给其他人。
  • 你也可以通过var = 666L强制python使用long变量
  • @Ignacio: 错误 A CPython int 是 C long (默认是有符号的)...见&lt;CPython 2.X source&gt;/Include/intobject.h: typedef struct { PyObject_HEAD long ob_ival; } PyIntObject;无论如何,Python 2.x int 允许负数;一个 C unsigned 就是应付不过来。
  • PEP 237 讨论了 Python 如何在幕后使这一切看起来完全一样。

标签: python integer


【解决方案1】:

intlong 是“统一的”a few versions back。在此之前,可以通过数学运算溢出 int。

3.x 进一步推进了这一点,完全消除了 long 并且只有 int。

  • Python 2sys.maxint 包含 Python int 可以容纳的最大值。
    • 在 64 位 Python 2.7 上,大小为 24 字节。请与sys.getsizeof()联系。
  • Python 3sys.maxsize 包含 Python int 可以达到的最大字节数。
    • 这将是 32 位的千兆字节和 64 位的艾字节。
    • 如此大的 int 值将类似于 8 的 sys.maxsize 的幂。

【讨论】:

  • 但是 Python3 将这种类型称为“int”,尽管它的行为更像 2.x 的“long”。
  • Ted 评论:如下所述,请注意将大于 maxint 的内容转换为 int 仍会导致 long >>>type(int(sys.maxint+1))
  • sys.maxint 会给你最大的 64 位整数(在我的 64 位机器上)一个 Long 可以比 64 位大得多,试试 "sys.maxint
  • 在python3中是sys.maxsize
  • sys.maxsize 与整数无关。 Python 3 的 sys.maxint 已被删除,因为没有整数的最大大小(Python 3 的 int 与 Python 2 的 long 相同)。
【解决方案2】:

只是继续这里给出的所有答案,尤其是@James Lanes

整数类型的大小可以用这个公式表示:

总范围 = (2 ^ 位系统)

下限 = -(2 ^ 位系统)*0.5 上限 = ((2 ^ 位系统)*0.5) - 1

【讨论】:

    【解决方案3】:

    Python 2 会根据值的大小自动设置类型。可以在下面找到最大值指南。

    Python 2 中默认 Int 的最大值为 65535,高于此值的任何值都会很长

    例如:

    >> print type(65535)
    <type 'int'>
    >>> print type(65536*65536)
    <type 'long'>
    

    在 Python 3 中,long 数据类型已被删除,所有整数值都由 Int 类处理。 Int 的默认大小取决于您的 CPU 架构。

    例如:

    • 32 位系统,整数的默认数据类型将是 'Int32'
    • 64 位系统,整数的默认数据类型为“Int64”

    每种类型的最小/最大值可以在下面找到:

    • Int8:[-128,127]
    • Int16:[-32768,32767]
    • Int32:[-2147483648,2147483647]
    • Int64:[-9223372036854775808,9223372036854775807]
    • Int128:[-170141183460469231731687303715884105728,170141183460469231731687303715884105727]
    • UInt8:[0,255]
    • UInt16:[0,65535]
    • UInt32:[0,4294967295]
    • UInt64:[0,18446744073709551615]
    • UInt128:[0,340282366920938463463374607431768211455]

    如果你的 Int 的大小超过了上面提到的限制,python 会自动改变它的类型并分配更多的内存来处理这个最小/最大值的增加。在 Python 2 中,它将转换为“long”,现在它只是转换为下一个 Int 大小。

    示例:如果您使用的是 32 位操作系统,则 Int 的最大值默认为 2147483647。如果赋值为 2147483648 或更大,则类型将更改为 Int64。

    有不同的方法来检查 int 的大小和它的内存分配。 注意:在 Python 3 中,使用内置的 type() 方法将始终返回 &lt;class 'int'&gt;,无论您使用什么大小的 Int。

    【讨论】:

    • 这是最详细的答案,但我不确定它对于 Python 3 是否足够详细(而 Python 2 信息可以删除)。那么任意长度的长度呢?直接使用 C 风格的类型怎么样,例如移植 C 代码或低级编程?
    • 在我典型的 64 位安装中,Python 2 中默认 int 的最大值不是 65535(我们中的某些人仍然对 Python 2 的行为感兴趣):mad@shuttle:~$ python --version; python -c 'print(type(0x7FFFffffFFFFffff))' Python 2.7.16 &lt;type 'int'&gt; mad@shuttle:~$
    • 如果 Int64 是默认的,Int8/Int16/Int32 将永远不会被使用,因为 Int64 已经比它们大了,当内部使用 Int8/Int16/Int32 时?
    【解决方案4】:

    Python 2.7.9 自动提升数字。 对于不确定使用 int() 或 long() 的情况。

    >>> a = int("123")
    >>> type(a)
    <type 'int'>
    >>> a = int("111111111111111111111111111111111111111111111111111")
    >>> type(a)
    <type 'long'>
    

    【讨论】:

      【解决方案5】:

      从 python 3.x 开始,统一整数库比旧版本更智能。在我的(i7 Ubuntu)盒子上,我得到了以下内容,

      >>> type(math.factorial(30))
      <class 'int'>
      

      有关实现细节,请参阅Include/longintrepr.h, Objects/longobject.c and Modules/mathmodule.c 文件。最后一个文件是一个动态模块(编译成一个so文件)。代码有很好的注释。

      【讨论】:

        【解决方案6】:

        有趣。在我的 64 位 (i7 Ubuntu) 机器上:

        >>> print type(0x7FFFFFFF)
        <type 'int'>
        >>> print type(0x7FFFFFFF+1)
        <type 'int'>
        

        猜猜它在更大的机器上最多可以达到 64 位整数。

        【讨论】:

        • Python 使用机器可用的较大整数类型。所以通常在 32 位机器上 int 将具有 32 位大小,而在 64 位机器上它将具有 64 位大小。但是可能存在定义 64 位整数的 32 位架构,在这种情况下,python 将使用 64 位整数。
        【解决方案7】:

        它管理它们,因为intlong 是同级类定义。它们具有用于 +、-、*、/ 等的适当方法,这些方法将产生适当类的结果。

        例如

        >>> a=1<<30
        >>> type(a)
        <type 'int'>
        >>> b=a*2
        >>> type(b)
        <type 'long'>
        

        在这种情况下,int 类有一个 __mul__ 方法(实现 * 的方法),它会在需要时创建 long 结果。

        【讨论】:

          【解决方案8】:

          在我的机器上:

          >>> print type(1<<30)
          <type 'int'>
          >>> print type(1<<31)
          <type 'long'>
          >>> print type(0x7FFFFFFF)
          <type 'int'>
          >>> print type(0x7FFFFFFF+1)
          <type 'long'>
          

          Python 对适合 32 位的值使用整数(32 位有符号整数,我不知道它们是否是 C 整数),但会自动切换到长整数(任意大位数 - 即 bignums ) 对于任何更大的东西。我猜这可以加快较小值的速度,同时避免任何溢出,并无缝过渡到 bignums。

          【讨论】:

            【解决方案9】:

            这个PEP 应该会有所帮助。

            底线是你真的不应该在 python 版本> 2.4 中担心它

            【讨论】:

            • 如果你必须用不适合 int 的东西(即 long)调用 c 中的 int 函数,你必须担心它。再多的铸造 long->int 也无济于事。最近发生在我身上。
            • @Macke:这条评论救了我,我认为 int 可以解决问题,但想知道为什么我仍然收到 Jython 异常。
            • @Macke 绝对正确。在我目前工作的公司,我们有一个用 Python 编写的模拟器,它通过 Tkinter 条目获取用户输入,并通过 TCP/IP 将转换后的值发送到模拟嵌入式系统的客户端(用 C/C++ 编写)。想象一下,当您在基于 Python 的条目中插入 100000000000000000000000 时会发生什么...:P
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-11-03
            • 1970-01-01
            • 2012-01-27
            • 1970-01-01
            • 2023-03-15
            相关资源
            最近更新 更多