elisp阶乘计算给出了错误的结果

时间:2013-01-27 00:17:52

标签: emacs elisp

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

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

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

4 个答案:

答案 0 :(得分:12)

处理大数字时,您始终可以调用Emacs的calc库。

(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

进一步阅读:

答案 1 :(得分:11)

整数有specific range。超出此范围的值无法表示。这是大多数(但不是全部)编程语言的标准。您可以通过检查most-positive-fixnum的值找到Emacs Lisp的整数数据类型可以在您的计算机上处​​理的最大数字。

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

答案 2 :(得分:4)

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

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

ELISP> (factorial 33)
8683317618811886495518194401280000000

但是,我试图通过另一种Calc方式获得乐趣,而不使用calc-evalstring。 因为使用Calc的更复杂的Emacs Lisp程序可以通过这种方式完成。

Calc的defmathcalcFunc-函数在Emacs Lisp中非常强大。

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

ELISP> (calcFunc-myFact 33)
8.683317618811886e+36

答案 3 :(得分: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 * cM-x calc 一起使用。