]> git.eshelyaron.com Git - emacs.git/commitdiff
(calculator-expt, calculator-integer-p): New functions.
authorJay Belanger <jay.p.belanger@gmail.com>
Wed, 4 Jul 2007 04:20:35 +0000 (04:20 +0000)
committerJay Belanger <jay.p.belanger@gmail.com>
Wed, 4 Jul 2007 04:20:35 +0000 (04:20 +0000)
(calculator-fact): Check to see if the factorial will be too large
before computing it.
(calculator-initial-operators): Use `calculator-expt' to compute "^".
(calculator-mode): Mention that results which are too large will return inf.

lisp/ChangeLog
lisp/calculator.el

index 9c8bb573e805c1258570235b47008bd982e56e44..e7ab6ae52d906cc9225c687854d70b20b1cb1d97 100644 (file)
@@ -1,3 +1,14 @@
+2007-07-03  Jay Belanger  <jay.p.belanger@gmail.com>
+
+       * calculator.el (calculator-expt, calculator-integer-p):
+       New functions.
+       (calculator-fact): Check to see if the factorial will be too
+       large before computing it.
+       (calculator-initial-operators): Use `calculator-expt' to
+       compute "^".
+       (calculator-mode): Mention that results which are too large
+       will return inf.
+
 2007-07-03  David Kastrup  <dak@gnu.org>
 
        * shell.el: On request of the authors, remove their addresses for
index 53a3c96d948a71ccfa4a6f34fe3c761909f8866c..c1e0edb627648896789e855a8c570c566cc930a7 100644 (file)
@@ -278,7 +278,7 @@ Examples:
     ("IC" acos (D (acos X))    x  6)
     ("IT" atan (D (atan X))    x  6)
     ("Q"  sqrt sqrt            x  7)
-    ("^"  ^    expt            2  7)
+    ("^"  ^    calculator-expt 2  7)
     ("!"  !    calculator-fact x  7)
     (";"  1/   (/ 1 X)         1  7)
     ("_"  -    -               1  8)
@@ -596,7 +596,8 @@ specified, then it is fixed, otherwise it depends on this variable).
 `+' and `-' can be used as either binary operators or prefix unary
 operators.  Numbers can be entered with exponential notation using `e',
 except when using a non-decimal radix mode for input (in this case `e'
-will be the hexadecimal digit).
+will be the hexadecimal digit).  If the result of a calculation is too
+large (out of range for Emacs), the value of \"inf\" is returned.
 
 Here are the editing keys:
 * `RET' `='      evaluate the current expression
@@ -1779,13 +1780,43 @@ To use this, apply a binary operator (evaluate it), then call this."
        (car calculator-last-opXY) (nth 1 calculator-last-opXY) x))
     x))
 
+(defun calculator-integer-p (x)
+  "Non-nil if X is equal to an integer."
+  (condition-case nil
+      (= x (ftruncate x))
+    (error nil)))
+
+(defun calculator-expt (x y)
+  "Compute X^Y, dealing with errors appropriately."
+  (condition-case
+      nil
+      (expt x y)
+    (domain-error 0.0e+NaN)
+    (range-error
+     (if (> y 0) 
+         (if (and
+              (< x 0)
+              (= y (truncate y))
+              (oddp (truncate y)))
+             -1.0e+INF
+           1.0e+INF)
+       0.0))
+    (error 0.0e+NaN)))
+
 (defun calculator-fact (x)
   "Simple factorial of X."
-  (let ((r (if (<= x 10) 1 1.0)))
-    (while (> x 0)
-      (setq r (* r (truncate x)))
-      (setq x (1- x)))
-    (+ 0.0 r)))
+  (if (and (>= x 0)
+           (calculator-integer-p x))
+      (if (= (calculator-expt (/ x 3.0) x) 1.0e+INF)
+          1.0e+INF
+        (let ((r (if (<= x 10) 1 1.0)))
+          (while (> x 0)
+            (setq r (* r (truncate x)))
+            (setq x (1- x)))
+          (+ 0.0 r)))
+    (if (= x 1.0e+INF)
+        x
+      0.0e+NaN)))
 
 (defun calculator-truncate (n)
   "Truncate N, return 0 in case of overflow."