]> git.eshelyaron.com Git - emacs.git/commitdiff
(math-emacs-precision, math-largest-emacs-expt)
authorJay Belanger <jay.p.belanger@gmail.com>
Sun, 22 Jul 2007 03:34:39 +0000 (03:34 +0000)
committerJay Belanger <jay.p.belanger@gmail.com>
Sun, 22 Jul 2007 03:34:39 +0000 (03:34 +0000)
(math-smallest-emacs-expt): New variables.
(math-use-emacs-fn): New function.
(math-exp-raw): Evaluate with `math-use-emacs-fn', when appropriate.

lisp/ChangeLog
lisp/calc/calc-math.el

index bba76763a5bc4a5a3ba92e533b646a4712125401..c0748aa82c1b2affc4b7f0b0bdd0090ba2cf3f2a 100644 (file)
@@ -1,3 +1,12 @@
+2007-07-21  Jay Belanger  <jay.p.belanger@gmail.com>
+
+       * calc/calc-math.el (math-emacs-precision)
+       (math-largest-emacs-expt, math-smallest-emacs-expt):
+       New variables.
+       (math-use-emacs-fn): New function.
+       (math-exp-raw): Evaluate with `math-use-emacs-fn', when
+       appropriate.
+
 2007-07-21  Thien-Thi Nguyen  <ttn@gnuvola.org>
 
        * image-dired.el (image-dired-sane-db-file): New func.
index d8de812421f4d80ed6ca014ad2ac99976760f0a8..dbafd138e454606311367c2df9a31825d851581c 100644 (file)
 (require 'calc-ext)
 (require 'calc-macs)
 
+
+;;; Find out how many 9s in 9.9999... will give distinct Emacs floats,
+;;; then back off by one.
+
+(defvar math-emacs-precision
+  (let* ((n 1)
+         (x 9)
+         (xx (+ x (* 9 (expt 10 (- n))))))
+    (while (/= x xx)
+      (progn
+        (setq n (1+ n))
+        (setq x xx)
+        (setq xx (+ x (* 9 (expt 10 (- n)))))))
+    (1- n))
+  "The number of digits in an Emacs float.")
+
+;;; Find the largest power of 10 which is an Emacs float, 
+;;; then back off by one so that any float d.dddd...eN 
+;;; is an Emacs float, for acceptable d.dddd....
+
+(defvar math-largest-emacs-expt
+  (let ((x 1))
+    (while (condition-case nil
+               (expt 10.0 x)
+             (error nil))
+      (setq x (* 2 x)))
+    (setq x (/ x 2))
+    (while (condition-case nil
+               (expt 10.0 x)
+             (error nil))
+      (setq x (1+ x)))
+    (- x 2))
+  "The largest exponent which Calc will convert to an Emacs float.")
+
+(defvar math-smallest-emacs-expt
+  (let ((x -1))
+    (while (condition-case nil
+               (expt 10.0 x)
+             (error nil))
+      (setq x (* 2 x)))
+    (setq x (/ x 2))
+    (while (condition-case nil
+               (expt 10.0 x)
+             (error nil))
+      (setq x (1- x)))
+    (+ x 2))
+    "The smallest exponent which Calc will convert to an Emacs float.")
+
+(defun math-use-emacs-fn (fn x)
+  "Use the native Emacs function FN to evaluate the Calc number X.
+If this can't be done, return NIL."
+  (and
+   (<= calc-internal-prec math-emacs-precision)
+   (math-realp x)
+   (let* ((fx (math-float x))
+          (xpon (+ (nth 2 x) (1- (math-numdigs (nth 1 x))))))
+     (and (<= math-smallest-emacs-expt xpon)
+          (<= xpon math-largest-emacs-expt)
+          (condition-case nil
+              (math-read-number
+               (number-to-string
+                (funcall fn 
+                         (string-to-number (math-format-number (math-float x))))))
+            (error nil))))))
+
 (defun calc-sqrt (arg)
   (interactive "P")
   (calc-slow-wrapper
           (list 'polar
                 (math-exp-raw (nth 1 xc))
                 (math-from-radians (nth 2 xc)))))
+        ((math-use-emacs-fn 'exp x))
        ((or (math-lessp-float '(float 5 -1) x)
             (math-lessp-float x '(float -5 -1)))
         (if (math-lessp-float '(float 921035 1) x)