【问题标题】:Python effective integer sizePython 有效整数大小
【发布时间】:2020-08-16 12:38:27
【问题描述】:

例如在 C#、C++、Java 或 JavaScript 中,有效的 int 大小是 32 位。如果我们要计算一些较大的数字,例如 70 位,我们应该使用一些软件功能(Arbitrary-precision arithmetic)。

Python 有一个非常棘手的整数内部无限表示,我无法弄清楚整数运算最有效的 int 大小是多少。

换句话说,我们是否有一些 int 大小,比如 64 位,以便有效地使用 int?

或者163264some random bits count 都没有关系,Python 将以相同的效率处理所有这些整数?

简而言之,Python 总是使用任意精度算术还是 32\64 使用硬件算术?

【问题讨论】:

  • 如果大小很重要,您可以使用 numpy。在这里您可以选择例如uint32 和 uint64。
  • 我不确定你在问什么,Python 整数 没有大小,你似乎已经明白了?
  • @Stefan 或者,您可以将array 模块用于原始的数字数组,这有时就足够了(如果您要进行任何繁重的处理,那么可能 numpy 就是您想要的)
  • 就您而言,任何特定int 对象的位长都是一个实现细节。我不明白你在这里问什么“我们是否有一些 int 大小,比如 64 位,用于有效的 ints 使用?”
  • @juanpa.arrivillaga 我们有两种算术。 Hardware,用于大小小于或等于 CPU 字的整数。 Software,当我们可以计算大数字(比 CPU 的字大),但使用一些代码时速度很慢。 Python 总是使用慢速软件算术吗?还是它使用 32/64 位的硬件算法?

标签: python integer long-integer integer-arithmetic


【解决方案1】:

CPython 的 int 在 Python 3 中表示为值的符号幅度数组,其中数组中的每个元素代表 15 或 30 位的幅度,分别用于 32 位和 64 位 Python 构建。这是一个实现细节,但却是一个长期存在的细节(最初一直是 15,但发现在 64 位系统上工作时,将数组中每个“数字”的大小和使用位数翻倍是一个容易的胜利。 )。它对ints 进行了优化,适合单个(或有时两个)这样的数组值(它从数组中提取原始值并执行单个 CPU 操作,跳过适用于任意长度情况的循环和算法),而在 CPython 的 64 位构建中,这目前意味着幅度为 30 位或更少的值通常会经过专门优化(60 位幅度有时具有快速路径)。

也就是说,很少有理由考虑到这一点; CPython 解释器开销非常高,很难想象手动将较大的操作分解为较小的操作(在 Python 层执行许多小操作会产生更多的解释器开销)会超过 Python 执行C 层基于数组的操作(即使没有特殊的快速路径)。这条规则的例外都依赖于非 Python-int-solutions,使用固定大小的 numpy 数组来向量化工作,并在那时很大程度上遵循 C 规则(因为 numpy 数组是原始 C 的包装器)大部分时间都是数组)。

【讨论】:

  • 我假设,优化的一个例子是here,它检查if (Py_ABS(Py_SIZE(a)) <= 1 && Py_ABS(Py_SIZE(b)) <= 1) { return PyLong_FromLong(MEDIUM_VALUE(a) + MEDIUM_VALUE(b));}
  • @juanpa.arrivillaga:是的。 MEDIUM_VALUE 是一个宏,它从底层数组中解包单个元素(并修复它的符号,因为数组值本身没有签名)。所以它只是将两者都解包,用普通的 CPU 指令添加它们,然后将它们重新打包成一个新的int
  • 这是否意味着 python 64 构建仅在 -2^29 到 2^29 -1 范围内有效地处理整数?
  • @NoNameQA: 范围是-2³⁰ - 12³⁰ - 1;该数组在每个元素中保存一个 30 位无符号幅度,并且符号以数组的大小进行编码(负数存储数组的负长度)。这个想法是当两个操作数都小到足以适应 32 位范围时,即使在乘法中也不会发生溢出,并且工作是使用 64 位操作数完成的。 30 位(而不是 31 位)的事情是由于通过简单地将所有数字翻倍来转换使用 16 位中的 15 位的算法相对容易。
  • sys.getsizeof可以看到效果;在我的 64 位构建中,sys.getsizeof(-(2**30) - 1) 是 28(字节),但 sys.getsizeof(-(2**30)) 是 32;当高位移动到第 31 位时,数组必须扩展。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
  • 1970-01-01
  • 2015-01-21
  • 1970-01-01
  • 2012-08-12
  • 2023-03-11
  • 1970-01-01
相关资源
最近更新 更多