5

我在 Lisp 教科书中读到这个:

Lisp 可以用数字完成一些惊人的壮举,尤其是与大多数其他语言相比时。例如,这里我们使用函数expt来计算 53 的 53 次方:

CL> (expt 53 53) 
24356848165022712132477606520104725518533453128685640844505130879576720609150223301256150373

大多数语言都会在涉及如此大数字的计算中窒息。

是的,这很酷,但是作者没有解释为什么 Lisp 比其他语言更容易和更快地做到这一点。

当然有一个简单的原因,有人可以解释吗?

4

2 回答 2

12

这是一个很好的例子,“更糟并不总是更好”

新泽西的方法

“传统”语言,如 C/C++/Java,基于硬件功能具有有限范围的整数算术,例如int32_t- 当结果不适合 32 位时,有符号的 32 位数字会静默溢出。这是非常快的,并且对于实际目的来说通常看起来足够好,但会导致难以发现的细微错误。

麻省理工学院/斯坦福大学风格

Lisp 采用了不同的方法。

它有一个“小”的未装箱整数类型fixnum,当 fixnum 算术的结果不适合 afixnum时,它会自动透明地提升为任意大小bignum,因此您总能得到数学上正确的结果。这意味着,除非编译器可以证明结果是 a fixnum,否则它必须添加代码来检查是否bignum必须分配 a 。实际上,这对现代建筑来说应该是 0 成本,但是当它在 4 多年前做出时,这是一个不平凡的决定。

“传统”语言,当他们提供大数算术时,以“图书馆”的方式做到这一点,即,

  • 它必须由用户明确要求;
  • bignums 以一种笨拙的方式操作:BigInteger.add(a,b)而不是a+b;
  • 即使实际数量很小并且适合机器int,也会产生成本。

请注意,Lisp 方法非常符合 Lisp以一些额外复杂性为代价做正确事情的传统。还体现在自动化的内存管理上,现在是主流,但在过去遭到了恶毒的攻击。整数运算的 lisp 方法现在已在其他一些语言(例如 python)中使用,因此正在取得进展

于 2013-10-30T13:43:34.773 回答
2

添加到 wvxvw 所写的内容,在 Lisp 中更容易,因为 bignums 内置在语言中。您可以像处理 C 或 Java 中的整数一样处理大量数字。

于 2013-10-30T10:35:57.990 回答