7

如果我在 emacs-lisp 中编写这个函数:

(defun factorial (n)
  (if (<= n 1)
      1
      (* n (factorial (- n 1)))))
      => factorial

它适用于像 5 或 10 这样的小数,但如果我尝试计算(阶乘 33)答案是 -1211487723752259584,这显然是错误的,所有大数都会破坏函数。在 python 中,这不会发生。是什么导致了这个问题?

4

4 回答 4

13

calc在处理大量数字时,您总是可以调用 Emacs 的库。

(defun factorial (n)
  (string-to-number (factorial--1 n)))

(defun factorial--1 (n)
  (if (<= n 1)
      "1"
    (calc-eval (format "%s * %s"
                       (number-to-string n)
                       (factorial--1 (- n 1))))))


ELISP> (factorial 33)  
8.683317618811886e+036

进一步阅读:

于 2013-01-27T02:17:11.283 回答
11

整数有一个特定的范围。超出此范围的值无法表示。这是大多数(但不是全部)编程语言的标准。您可以通过检查most-positive-fixnum.

转到您的*scratch*缓冲区(或任何 Lisp 缓冲区)并输入most-positive-fixnum. 将光标放在末尾,然后按C-x C-e。在我的电脑上,我得到 2305843009213693951 作为值。你的可能会有所不同:我在 64 位机器上,这个数字大约是2^61. 33 的阶乘的解是 8683317618811886495518194401280000000。大约是 2^86,这也超出了我的 Emacs 可以处理的范围。(我使用Arc来精确计算它,因为 Arc 可以表示任何大小的整数,受制于您安装的内存量等无聊的东西)。

于 2013-01-27T00:59:37.170 回答
6

最简单的解决方案似乎是保罗的解决方案:

(defun factorial (n) (calc-eval (format "%s!" n)))

ELISP> (factorial 33)
8683317618811886495518194401280000000

但是,我尝试通过另一种 Calc 方式来取乐,而不使用calc-eval and string。因为使用 Calc 的更复杂的 Emacs Lisp 程序可以通过这种方式完成。

CalcdefmathcalcFunc-函数在 Emacs Lisp 中非常强大。

(defmath myFact (n) (string-to-number (format-number (calcFunc-fact n))))

ELISP> (calcFunc-myFact 33)
8.683317618811886e+36
于 2015-07-13T12:51:56.387 回答
0

我找到了这个问题,寻找一种在 Elisp 中计算阶乘的快速简便的方法,最好实现它。

从其他答案中,我推测它是:

(calc-eval "10!")

这相当于

(calc-eval "fact(10)")

它与重新定义阶乘函数一样简洁且功能更强大。例如,您可以通过这种方式获得二项式系数:

(calc-eval "7!/3!(7-3)!")

甚至这样:

(calc-eval "choose(7,3)")

Calc真的很值得探索。我建议在 Emacs 中做交互式教程。您可以使用C-x * t. 至于 calc,您可以将其与C-x * c、 或 一起使用M-x calc

于 2021-03-24T18:55:20.100 回答