comparison lisp/calc/calc-math.el @ 82015:0795e1e56274

(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.
author Jay Belanger <jay.p.belanger@gmail.com>
date Sun, 22 Jul 2007 03:33:02 +0000
parents 71ae866366dc
children b98604865ea0 492971a3f31f
comparison
equal deleted inserted replaced
82014:f756878ad88b 82015:0795e1e56274
29 29
30 ;; This file is autoloaded from calc-ext.el. 30 ;; This file is autoloaded from calc-ext.el.
31 31
32 (require 'calc-ext) 32 (require 'calc-ext)
33 (require 'calc-macs) 33 (require 'calc-macs)
34
35
36 ;;; Find out how many 9s in 9.9999... will give distinct Emacs floats,
37 ;;; then back off by one.
38
39 (defvar math-emacs-precision
40 (let* ((n 1)
41 (x 9)
42 (xx (+ x (* 9 (expt 10 (- n))))))
43 (while (/= x xx)
44 (progn
45 (setq n (1+ n))
46 (setq x xx)
47 (setq xx (+ x (* 9 (expt 10 (- n)))))))
48 (1- n))
49 "The number of digits in an Emacs float.")
50
51 ;;; Find the largest power of 10 which is an Emacs float,
52 ;;; then back off by one so that any float d.dddd...eN
53 ;;; is an Emacs float, for acceptable d.dddd....
54
55 (defvar math-largest-emacs-expt
56 (let ((x 1))
57 (while (condition-case nil
58 (expt 10.0 x)
59 (error nil))
60 (setq x (* 2 x)))
61 (setq x (/ x 2))
62 (while (condition-case nil
63 (expt 10.0 x)
64 (error nil))
65 (setq x (1+ x)))
66 (- x 2))
67 "The largest exponent which Calc will convert to an Emacs float.")
68
69 (defvar math-smallest-emacs-expt
70 (let ((x -1))
71 (while (condition-case nil
72 (expt 10.0 x)
73 (error nil))
74 (setq x (* 2 x)))
75 (setq x (/ x 2))
76 (while (condition-case nil
77 (expt 10.0 x)
78 (error nil))
79 (setq x (1- x)))
80 (+ x 2))
81 "The smallest exponent which Calc will convert to an Emacs float.")
82
83 (defun math-use-emacs-fn (fn x)
84 "Use the native Emacs function FN to evaluate the Calc number X.
85 If this can't be done, return NIL."
86 (and
87 (<= calc-internal-prec math-emacs-precision)
88 (math-realp x)
89 (let* ((fx (math-float x))
90 (xpon (+ (nth 2 x) (1- (math-numdigs (nth 1 x))))))
91 (and (<= math-smallest-emacs-expt xpon)
92 (<= xpon math-largest-emacs-expt)
93 (condition-case nil
94 (math-read-number
95 (number-to-string
96 (funcall fn
97 (string-to-number (math-format-number (math-float x))))))
98 (error nil))))))
34 99
35 (defun calc-sqrt (arg) 100 (defun calc-sqrt (arg)
36 (interactive "P") 101 (interactive "P")
37 (calc-slow-wrapper 102 (calc-slow-wrapper
38 (if (calc-is-inverse) 103 (if (calc-is-inverse)
1401 ((eq (car x) 'polar) 1466 ((eq (car x) 'polar)
1402 (let ((xc (math-complex x))) 1467 (let ((xc (math-complex x)))
1403 (list 'polar 1468 (list 'polar
1404 (math-exp-raw (nth 1 xc)) 1469 (math-exp-raw (nth 1 xc))
1405 (math-from-radians (nth 2 xc))))) 1470 (math-from-radians (nth 2 xc)))))
1471 ((math-use-emacs-fn 'exp x))
1406 ((or (math-lessp-float '(float 5 -1) x) 1472 ((or (math-lessp-float '(float 5 -1) x)
1407 (math-lessp-float x '(float -5 -1))) 1473 (math-lessp-float x '(float -5 -1)))
1408 (if (math-lessp-float '(float 921035 1) x) 1474 (if (math-lessp-float '(float 921035 1) x)
1409 (math-overflow) 1475 (math-overflow)
1410 (if (math-lessp-float x '(float -921035 1)) 1476 (if (math-lessp-float x '(float -921035 1))