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

整数には特定の範囲があります。この範囲外の値は表現できません。これは、すべてではありませんが、ほとんどのプログラミング言語で非常に標準的です。の値をチェックすることで、Emacs Lisp の整数データ型がコンピュータで処理できる最大数を見つけることができます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

最も単純な解決策は、Paul のもののようです。

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

ELISP> (factorial 33)
8683317618811886495518194401280000000

calc-eval ただし、 と を使用せずに、別の Calc の方法で楽しみのために試してみました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 に答える