Mercurial > emacs
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)) |