在C,Python和Scheme中使用factorial程序进行一些随机实验。我遇到了这个事实:
在C中,使用'unsigned long long'数据类型,我可以打印的最大因子是65.这是'9223372036854775808',指定为here的19位数。
在Python中,我可以找到一个大小为999的阶乘,它由大量数字组成,远远超过19。
CPython如何实现这一目标?它是否使用“octaword”之类的数据类型?
我可能会遗漏一些基本事实。所以,我会很感激一些见解和/或参考阅读。谢谢!
更新:谢谢大家的解释。这是否意味着,CPython正在使用GNU多精度库(或其他类似的库)?
更新2:我在源代码中寻找Python的'bignum'实现。到底在哪里?它在http://svn.python.org/view/python/trunk/Objects/longobject.c?view=markup。谢谢Baishampayan。
答案 0 :(得分:9)
它被称为任意精度算术。这里还有更多:http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic
答案 1 :(得分:6)
查看Python源代码,似乎long
类型(至少在Python 3之前的代码中)在longintrepr.h中定义如下 -
/* Long integer representation.
The absolute value of a number is equal to
SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i)
Negative numbers are represented with ob_size < 0;
zero is represented by ob_size == 0.
In a normalized number, ob_digit[abs(ob_size)-1] (the most significant
digit) is never zero. Also, in all cases, for all valid i,
0 <= ob_digit[i] <= MASK.
The allocation function takes care of allocating extra memory
so that ob_digit[0] ... ob_digit[abs(ob_size)-1] are actually available.
CAUTION: Generic code manipulating subtypes of PyVarObject has to
aware that longs abuse ob_size's sign bit.
*/
struct _longobject {
PyObject_VAR_HEAD
digit ob_digit[1];
};
然后通过创建一个像这样的新类型PyLongObject在longobject.h中定义long
类型的实际可用接口 -
typedef struct _longobject PyLongObject;
等等。
longobject.c内发生了更多事情,您可以查看这些内容以获取更多详情。
答案 2 :(得分:4)
C中的int
等数据类型直接映射(或多或少)到处理器支持的数据类型。因此,对C int
的限制基本上是处理器硬件所施加的限制。
但是,人们可以完全用软件实现自己的int
数据类型。例如,您可以使用数字数组作为基础表示。可能是这样的:
class MyInt {
private int [] digits;
public MyInt(int noOfDigits) {
digits = new int[noOfDigits];
}
}
一旦你这样做,你可以使用这个类并存储包含任意数量的数字的整数,只要你没有耗尽内存。
也许Python在其虚拟机中做了类似的事情。您可能需要阅读有关任意精度算术的this article以获取详细信息。
答案 3 :(得分:3)
不是八角。它实现了bignum结构来存储任意精度的数字。
答案 4 :(得分:1)
Python将long
整数(Python 3中的所有int
)分配给他们需要的空间 - 根据需要分配的“数字”数组(基数为2的幂)