summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authorJay Belanger <jay.p.belanger@gmail.com>2007-07-22 03:34:39 +0000
committerJay Belanger <jay.p.belanger@gmail.com>2007-07-22 03:34:39 +0000
commit178b8bafc21e226d1a81df50ec50616a04fb93a1 (patch)
tree7403465e8d56b8a72ac7022b7ae0d942a03b1682 /lisp
parenta226e0ef9cf6a6be1e095a3b73c817b71777843b (diff)
downloademacs-178b8bafc21e226d1a81df50ec50616a04fb93a1.tar.gz
(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.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog9
-rw-r--r--lisp/calc/calc-math.el66
2 files changed, 75 insertions, 0 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index bba76763a5b..c0748aa82c1 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -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.
diff --git a/lisp/calc/calc-math.el b/lisp/calc/calc-math.el
index d8de812421f..dbafd138e45 100644
--- a/lisp/calc/calc-math.el
+++ b/lisp/calc/calc-math.el
@@ -32,6 +32,71 @@
(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
@@ -1403,6 +1468,7 @@
(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)