summaryrefslogtreecommitdiff
path: root/lisp/calc
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>2007-07-09 08:00:55 +0000
committerMiles Bader <miles@gnu.org>2007-07-09 08:00:55 +0000
commit1011c48763982d02797a7058556d29f639f6efca (patch)
tree5f1b7529b4cc483b73475b89245633c5848b8a5e /lisp/calc
parent6f06dac7b57b8d73f4b26a855cd9862630192029 (diff)
parent69e4c7c4bacf19e9e004605fcb1c067e478beffe (diff)
downloademacs-1011c48763982d02797a7058556d29f639f6efca.tar.gz
emacs-1011c48763982d02797a7058556d29f639f6efca.tar.bz2
emacs-1011c48763982d02797a7058556d29f639f6efca.zip
Merge from emacs--devo--0
Patches applied: * emacs--devo--0 (patch 803-805) - Update from CVS Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-227
Diffstat (limited to 'lisp/calc')
-rw-r--r--lisp/calc/calc-aent.el12
-rw-r--r--lisp/calc/calc-bin.el58
-rw-r--r--lisp/calc/calc-comb.el75
-rw-r--r--lisp/calc/calc-embed.el2
-rw-r--r--lisp/calc/calc-ext.el46
-rw-r--r--lisp/calc/calc-forms.el28
-rw-r--r--lisp/calc/calc-funcs.el233
-rw-r--r--lisp/calc/calc-lang.el4
-rw-r--r--lisp/calc/calc-math.el25
-rw-r--r--lisp/calc/calc-misc.el2
-rw-r--r--lisp/calc/calc-poly.el6
-rw-r--r--lisp/calc/calc-prog.el2
-rw-r--r--lisp/calc/calc-yank.el2
-rw-r--r--lisp/calc/calc.el258
-rw-r--r--lisp/calc/calccomp.el1
15 files changed, 491 insertions, 263 deletions
diff --git a/lisp/calc/calc-aent.el b/lisp/calc/calc-aent.el
index 4b954fabd0c..be77030c914 100644
--- a/lisp/calc/calc-aent.el
+++ b/lisp/calc/calc-aent.el
@@ -100,7 +100,7 @@
(cond
((and (consp str) (not (symbolp (car str))))
(let ((calc-language nil)
- (math-expr-opers math-standard-opers)
+ (math-expr-opers (math-standard-ops))
(calc-internal-prec 12)
(calc-word-size 32)
(calc-symbolic-mode nil)
@@ -254,7 +254,7 @@ The value t means abort and give an error message.")
(interactive "P")
(calc-wrapper
(let ((calc-language (if prefix nil calc-language))
- (math-expr-opers (if prefix math-standard-opers math-expr-opers)))
+ (math-expr-opers (if prefix (math-standard-ops) (math-expr-ops))))
(calc-alg-entry (and auto (char-to-string last-command-char))))))
(defvar calc-alg-entry-history nil
@@ -876,7 +876,10 @@ in Calc algebraic input.")
calcFunc-eq calcFunc-neq))
(defun math-read-expr-level (exp-prec &optional exp-term)
- (let* ((x (math-read-factor)) (first t) op op2)
+ (let* ((math-expr-opers (math-expr-ops))
+ (x (math-read-factor))
+ (first t)
+ op op2)
(while (and (or (and calc-user-parse-table
(setq op (calc-check-user-syntax x exp-prec))
(setq x op
@@ -1121,7 +1124,8 @@ in Calc algebraic input.")
(assoc math-expr-data '(("(") ("[") ("{"))))))
(defun math-read-factor ()
- (let (op)
+ (let ((math-expr-opers (math-expr-ops))
+ op)
(cond ((eq math-exp-token 'number)
(let ((num (math-read-number math-expr-data)))
(if (not num)
diff --git a/lisp/calc/calc-bin.el b/lisp/calc/calc-bin.el
index 3963700a599..2dde6216a06 100644
--- a/lisp/calc/calc-bin.el
+++ b/lisp/calc/calc-bin.el
@@ -32,6 +32,17 @@
(require 'calc-ext)
(require 'calc-macs)
+;;; Some useful numbers
+(defconst math-bignum-logb-digit-size
+ (eval-when-compile (logb math-bignum-digit-size))
+ "The logb of the size of a bignum digit.
+This is the largest value of B such that 2^B is less than
+the size of a Calc bignum digit.")
+
+(defconst math-bignum-digit-power-of-two
+ (eval-when-compile (expt 2 (logb math-bignum-digit-size)))
+ "The largest power of 2 less than the size of a Calc bignum digit.")
+
;;; b-prefix binary commands.
(defun calc-and (n)
@@ -297,11 +308,11 @@
(defun math-and-bignum (a b) ; [l l l]
(and a b
- (let ((qa (math-div-bignum-digit a 512))
- (qb (math-div-bignum-digit b 512)))
+ (let ((qa (math-div-bignum-digit a math-bignum-digit-power-of-two))
+ (qb (math-div-bignum-digit b math-bignum-digit-power-of-two)))
(math-mul-bignum-digit (math-and-bignum (math-norm-bignum (car qa))
(math-norm-bignum (car qb)))
- 512
+ math-bignum-digit-power-of-two
(logand (cdr qa) (cdr qb))))))
(defun calcFunc-or (a b &optional w) ; [I I I] [Public]
@@ -324,11 +335,11 @@
(defun math-or-bignum (a b) ; [l l l]
(and (or a b)
- (let ((qa (math-div-bignum-digit a 512))
- (qb (math-div-bignum-digit b 512)))
+ (let ((qa (math-div-bignum-digit a math-bignum-digit-power-of-two))
+ (qb (math-div-bignum-digit b math-bignum-digit-power-of-two)))
(math-mul-bignum-digit (math-or-bignum (math-norm-bignum (car qa))
(math-norm-bignum (car qb)))
- 512
+ math-bignum-digit-power-of-two
(logior (cdr qa) (cdr qb))))))
(defun calcFunc-xor (a b &optional w) ; [I I I] [Public]
@@ -351,11 +362,11 @@
(defun math-xor-bignum (a b) ; [l l l]
(and (or a b)
- (let ((qa (math-div-bignum-digit a 512))
- (qb (math-div-bignum-digit b 512)))
+ (let ((qa (math-div-bignum-digit a math-bignum-digit-power-of-two))
+ (qb (math-div-bignum-digit b math-bignum-digit-power-of-two)))
(math-mul-bignum-digit (math-xor-bignum (math-norm-bignum (car qa))
(math-norm-bignum (car qb)))
- 512
+ math-bignum-digit-power-of-two
(logxor (cdr qa) (cdr qb))))))
(defun calcFunc-diff (a b &optional w) ; [I I I] [Public]
@@ -378,11 +389,11 @@
(defun math-diff-bignum (a b) ; [l l l]
(and a
- (let ((qa (math-div-bignum-digit a 512))
- (qb (math-div-bignum-digit b 512)))
+ (let ((qa (math-div-bignum-digit a math-bignum-digit-power-of-two))
+ (qb (math-div-bignum-digit b math-bignum-digit-power-of-two)))
(math-mul-bignum-digit (math-diff-bignum (math-norm-bignum (car qa))
(math-norm-bignum (car qb)))
- 512
+ math-bignum-digit-power-of-two
(logand (cdr qa) (lognot (cdr qb)))))))
(defun calcFunc-not (a &optional w) ; [I I] [Public]
@@ -402,14 +413,15 @@
w))))))
(defun math-not-bignum (a w) ; [l l]
- (let ((q (math-div-bignum-digit a 512)))
- (if (<= w 9)
+ (let ((q (math-div-bignum-digit a math-bignum-digit-power-of-two)))
+ (if (<= w math-bignum-logb-digit-size)
(list (logand (lognot (cdr q))
(1- (lsh 1 w))))
(math-mul-bignum-digit (math-not-bignum (math-norm-bignum (car q))
- (- w 9))
- 512
- (logxor (cdr q) 511)))))
+ (- w math-bignum-logb-digit-size))
+ math-bignum-digit-power-of-two
+ (logxor (cdr q)
+ (1- math-bignum-digit-power-of-two))))))
(defun calcFunc-lsh (a &optional n w) ; [I I] [Public]
(setq a (math-trunc a)
@@ -510,8 +522,8 @@
(math-sub a (math-power-of-2 (- w)))))
((Math-negp a)
(math-normalize (cons 'bigpos (math-binary-arg a w))))
- ((and (integerp a) (< a 1000000))
- (if (>= w 20)
+ ((and (integerp a) (< a math-small-integer-size))
+ (if (> w (logb math-small-integer-size))
a
(logand a (1- (lsh 1 w)))))
(t
@@ -523,13 +535,13 @@
(defalias 'calcFunc-clip 'math-clip)
(defun math-clip-bignum (a w) ; [l l]
- (let ((q (math-div-bignum-digit a 512)))
- (if (<= w 9)
+ (let ((q (math-div-bignum-digit a math-bignum-digit-power-of-two)))
+ (if (<= w math-bignum-logb-digit-size)
(list (logand (cdr q)
(1- (lsh 1 w))))
(math-mul-bignum-digit (math-clip-bignum (math-norm-bignum (car q))
- (- w 9))
- 512
+ (- w math-bignum-logb-digit-size))
+ math-bignum-digit-power-of-two
(cdr q)))))
(defvar math-max-digits-cache nil)
diff --git a/lisp/calc/calc-comb.el b/lisp/calc/calc-comb.el
index 6c30177a0b0..c933ecd7e00 100644
--- a/lisp/calc/calc-comb.el
+++ b/lisp/calc/calc-comb.el
@@ -294,6 +294,19 @@
;;; Factorial and related functions.
+(defconst math-small-factorial-table
+ (eval-when-compile
+ (vector 1 1 2 6 24 120 720 5040 40320 362880 3628800 39916800
+ (math-read-number-simple "479001600")
+ (math-read-number-simple "6227020800")
+ (math-read-number-simple "87178291200")
+ (math-read-number-simple "1307674368000")
+ (math-read-number-simple "20922789888000")
+ (math-read-number-simple "355687428096000")
+ (math-read-number-simple "6402373705728000")
+ (math-read-number-simple "121645100408832000")
+ (math-read-number-simple "2432902008176640000"))))
+
(defun calcFunc-fact (n) ; [I I] [F F] [Public]
(let (temp)
(cond ((Math-integer-negp n)
@@ -302,14 +315,7 @@
(math-reject-arg n 'range)))
((integerp n)
(if (<= n 20)
- (aref '[1 1 2 6 24 120 720 5040 40320 362880
- (bigpos 800 628 3) (bigpos 800 916 39)
- (bigpos 600 1 479) (bigpos 800 20 227 6)
- (bigpos 200 291 178 87) (bigpos 0 368 674 307 1)
- (bigpos 0 888 789 922 20) (bigpos 0 96 428 687 355)
- (bigpos 0 728 705 373 402 6)
- (bigpos 0 832 408 100 645 121)
- (bigpos 0 640 176 8 902 432 2)] n)
+ (aref math-small-factorial-table n)
(math-factorial-iter (1- n) 2 1)))
((and (math-messy-integerp n)
(Math-lessp n 100))
@@ -551,9 +557,9 @@
nil
(if (Math-integerp var-RandSeed)
(let* ((seed (math-sub 161803 var-RandSeed))
- (mj (1+ (math-mod seed '(bigpos 0 0 1))))
- (mk (1+ (math-mod (math-quotient seed '(bigpos 0 0 1))
- '(bigpos 0 0 1))))
+ (mj (1+ (math-mod seed 1000000)))
+ (mk (1+ (math-mod (math-quotient seed 1000000)
+ 1000000)))
(i 0))
(setq math-random-table (cons 'vec (make-list 55 mj)))
(while (<= (setq i (1+ i)) 54)
@@ -601,7 +607,8 @@
;;; Avoid various pitfalls that may lurk in the built-in (random) function!
;;; Shuffling algorithm from Numerical Recipes, section 7.1.
(defvar math-random-last)
-(defun math-random-digit ()
+(defun math-random-three-digit-number ()
+ "Return a random three digit number."
(let (i)
(or (and (boundp 'var-RandSeed) (eq var-RandSeed math-last-RandSeed))
(math-init-random-base))
@@ -621,17 +628,17 @@
;;; Produce an N-digit random integer.
(defun math-random-digits (n)
- (cond ((<= n 6)
- (math-scale-right (+ (* (math-random-digit) 1000) (math-random-digit))
- (- 6 n)))
- (t (let* ((slop (% (- 900003 n) 3))
- (i (/ (+ n slop) 3))
- (digs nil))
- (while (> i 0)
- (setq digs (cons (math-random-digit) digs)
- i (1- i)))
- (math-normalize (math-scale-right (cons 'bigpos digs)
- slop))))))
+ "Produce a random N digit integer."
+ (let* ((slop (% (- 3 (% n 3)) 3))
+ (i (/ (+ n slop) 3))
+ (rnum 0))
+ (while (> i 0)
+ (setq rnum
+ (math-add
+ (math-random-three-digit-number)
+ (math-mul rnum 1000)))
+ (setq i (1- i)))
+ (math-normalize (math-scale-right rnum slop))))
;;; Produce a uniformly-distributed random float 0 <= N < 1.
(defun math-random-float ()
@@ -802,7 +809,7 @@
(error "Argument must be an integer"))
((Math-integer-negp n)
'(nil))
- ((Math-natnum-lessp n '(bigpos 0 0 8))
+ ((Math-natnum-lessp n 8000000)
(setq n (math-fixnum n))
(let ((i -1) v)
(while (and (> (% n (setq v (aref math-primes-table
@@ -815,15 +822,17 @@
((not (equal n (car math-prime-test-cache)))
(cond ((= (% (nth 1 n) 2) 0) '(nil 2))
((= (% (nth 1 n) 5) 0) '(nil 5))
- (t (let ((dig (cdr n)) (sum 0))
- (while dig
- (if (cdr dig)
- (setq sum (% (+ (+ sum (car dig))
- (* (nth 1 dig) 1000))
- 111111)
- dig (cdr (cdr dig)))
- (setq sum (% (+ sum (car dig)) 111111)
- dig nil)))
+ (t (let ((q n) (sum 0))
+ (while (not (eq q 0))
+ (setq sum (%
+ (+
+ sum
+ (calcFunc-mod
+ q 1000000))
+ 111111))
+ (setq q
+ (math-quotient
+ q 1000000)))
(cond ((= (% sum 3) 0) '(nil 3))
((= (% sum 7) 0) '(nil 7))
((= (% sum 11) 0) '(nil 11))
diff --git a/lisp/calc/calc-embed.el b/lisp/calc/calc-embed.el
index a064905943f..f31c19e3390 100644
--- a/lisp/calc/calc-embed.el
+++ b/lisp/calc/calc-embed.el
@@ -403,7 +403,7 @@
(let ((val (save-excursion
(set-buffer (aref info 1))
(let ((calc-language nil)
- (math-expr-opers math-standard-opers))
+ (math-expr-opers (math-standard-ops)))
(math-read-expr str)))))
(if (eq (car-safe val) 'error)
(progn
diff --git a/lisp/calc/calc-ext.el b/lisp/calc/calc-ext.el
index ca89928d46e..65383df308c 100644
--- a/lisp/calc/calc-ext.el
+++ b/lisp/calc/calc-ext.el
@@ -1878,8 +1878,19 @@ calc-kill calc-kill-region calc-yank))))
(last-prec (intern (concat (symbol-name name) "-last-prec")))
(last-val (intern (concat (symbol-name name) "-last"))))
(list 'progn
- (list 'defvar cache-prec (if init (math-numdigs (nth 1 init)) -100))
- (list 'defvar cache-val (list 'quote init))
+; (list 'defvar cache-prec (if init (math-numdigs (nth 1 init)) -100))
+ (list 'defvar cache-prec
+ `(cond
+ ((consp ,init) (math-numdigs (nth 1 ,init)))
+ (,init
+ (nth 1 (math-numdigs (eval ,init))))
+ (t
+ -100)))
+ (list 'defvar cache-val
+ `(cond
+ ((consp ,init) ,init)
+ (,init (eval ,init))
+ (t ,init)))
(list 'defvar last-prec -100)
(list 'defvar last-val nil)
(list 'setq 'math-cache-list
@@ -1914,7 +1925,12 @@ calc-kill calc-kill-region calc-yank))))
(put 'math-defcache 'lisp-indent-hook 2)
;;; Betcha didn't know that pi = 16 atan(1/5) - 4 atan(1/239). [F] [Public]
-(math-defcache math-pi (float (bigpos 463 238 793 589 653 592 141 3) -21)
+(defconst math-approx-pi
+ (eval-when-compile
+ (math-read-number-simple "3.141592653589793238463"))
+ "An approximation for pi.")
+
+(math-defcache math-pi math-approx-pi
(math-add-float (math-mul-float '(float 16 0)
(math-arctan-raw '(float 2 -1)))
(math-mul-float '(float -4 0)
@@ -1945,7 +1961,11 @@ calc-kill calc-kill-region calc-yank))))
(math-defcache math-sqrt-two-pi nil
(math-sqrt-float (math-two-pi)))
-(math-defcache math-sqrt-e (float (bigpos 849 146 128 700 270 721 648 1) -21)
+(defconst math-approx-sqrt-e
+ (eval-when-compile (math-read-number-simple "1.648721270700128146849"))
+ "An approximation for sqrt(3).")
+
+(math-defcache math-sqrt-e math-approx-sqrt-e
(math-add-float '(float 1 0) (math-exp-minus-1-raw '(float 5 -1))))
(math-defcache math-e nil
@@ -1955,10 +1975,14 @@ calc-kill calc-kill-region calc-yank))))
(math-mul-float (math-add-float (math-sqrt-raw '(float 5 0)) '(float 1 0))
'(float 5 -1)))
-(math-defcache math-gamma-const nil
- '(float (bigpos 495 467 917 632 470 369 709 646 776 267 677 848 348 672
- 057 988 235 399 359 593 421 310 024 824 900 120 065 606
- 328 015 649 156 772 5) -100))
+(defconst math-approx-gamma-const
+ (eval-when-compile
+ (math-read-number-simple
+ "0.5772156649015328606065120900824024310421593359399235988057672348848677267776646709369470632917467495"))
+ "An approximation for gamma.")
+
+(math-defcache math-gamma-const nil
+ math-approx-gamma-const)
(defun math-half-circle (symb)
(if (eq calc-angle-mode 'rad)
@@ -2202,7 +2226,7 @@ calc-kill calc-kill-region calc-yank))))
(defun math-fixnum-big (a)
(if (cdr a)
- (+ (car a) (* (math-fixnum-big (cdr a)) 1000))
+ (+ (car a) (* (math-fixnum-big (cdr a)) math-bignum-digit-size))
(car a)))
(defvar math-simplify-only nil)
@@ -2960,7 +2984,7 @@ calc-kill calc-kill-region calc-yank))))
(defun math-read-plain-expr (exp-str &optional error-check)
(let* ((calc-language nil)
- (math-expr-opers math-standard-opers)
+ (math-expr-opers (math-standard-ops))
(val (math-read-expr exp-str)))
(and error-check
(eq (car-safe val) 'error)
@@ -3116,7 +3140,7 @@ calc-kill calc-kill-region calc-yank))))
(concat (substring (symbol-name (car a)) 9)
"(" (math-vector-to-string (nth 1 a) t) ")"))
(t
- (let ((op (math-assq2 (car a) math-standard-opers)))
+ (let ((op (math-assq2 (car a) (math-standard-ops))))
(cond ((and op (= (length a) 3))
(if (> prec (min (nth 2 op) (nth 3 op)))
(concat "(" (math-format-flat-expr a 0) ")")
diff --git a/lisp/calc/calc-forms.el b/lisp/calc/calc-forms.el
index 10bbf7dc3dd..5f319800999 100644
--- a/lisp/calc/calc-forms.el
+++ b/lisp/calc/calc-forms.el
@@ -544,6 +544,14 @@
(setcdr math-fd-dt nil))
fmt))))
+(defconst math-julian-date-beginning '(float 17214235 -1)
+ "The beginning of the Julian calendar,
+as measured in the number of days before January 1 of the year 1AD.")
+
+(defconst math-julian-date-beginning-int 1721424
+ "The beginning of the Julian calendar,
+as measured in the integer number of days before January 1 of the year 1AD.")
+
(defun math-format-date-part (x)
(cond ((stringp x)
x)
@@ -558,9 +566,12 @@
((eq x 'n)
(math-format-number (math-floor math-fd-date)))
((eq x 'J)
- (math-format-number (math-add math-fd-date '(float (bigpos 235 214 17) -1))))
+ (math-format-number
+ (math-add math-fd-date math-julian-date-beginning)))
((eq x 'j)
- (math-format-number (math-add (math-floor math-fd-date) '(bigpos 424 721 1))))
+ (math-format-number (math-add
+ (math-floor math-fd-date)
+ math-julian-date-beginning-int)))
((eq x 'U)
(math-format-number (nth 1 (math-date-parts math-fd-date 719164))))
((progn
@@ -935,9 +946,8 @@
0
(if (or (eq this 'j)
(math-integerp num))
- '(bigpos 424 721 1)
- '(float (bigpos 235 214 17)
- -1))))
+ math-julian-date-beginning-int
+ math-julian-date-beginning)))
hour (or (nth 3 num) hour)
minute (or (nth 4 num) minute)
second (or (nth 5 num) second)
@@ -1146,14 +1156,14 @@
(defun calcFunc-julian (date &optional zone)
(if (math-realp date)
(list 'date (if (math-integerp date)
- (math-sub date '(bigpos 424 721 1))
- (setq date (math-sub date '(float (bigpos 235 214 17) -1)))
+ (math-sub date math-julian-date-beginning-int)
+ (setq date (math-sub date math-julian-date-beginning))
(math-sub date (math-div (calcFunc-tzone zone date)
'(float 864 2)))))
(if (eq (car date) 'date)
(math-add (nth 1 date) (if (math-integerp (nth 1 date))
- '(bigpos 424 721 1)
- (math-add '(float (bigpos 235 214 17) -1)
+ math-julian-date-beginning-int
+ (math-add math-julian-date-beginning
(math-div (calcFunc-tzone zone date)
'(float 864 2)))))
(math-reject-arg date 'datep))))
diff --git a/lisp/calc/calc-funcs.el b/lisp/calc/calc-funcs.el
index 479116b0c76..78d0df34cdb 100644
--- a/lisp/calc/calc-funcs.el
+++ b/lisp/calc/calc-funcs.el
@@ -147,7 +147,8 @@
(or (math-numberp x) (math-reject-arg x 'numberp))
(calcFunc-fact (math-add x -1)))
-(defun math-gammap1-raw (x &optional fprec nfprec) ; compute gamma(1 + x)
+(defun math-gammap1-raw (x &optional fprec nfprec)
+ "Compute gamma(1+X) to the appropriate precision."
(or fprec
(setq fprec (math-float calc-internal-prec)
nfprec (math-float (- calc-internal-prec))))
@@ -567,42 +568,54 @@
((Math-lessp '(float 8 0) (math-abs-approx x))
(let* ((z (math-div '(float 8 0) x))
(y (math-sqr z))
- (xx (math-add x '(float (bigneg 164 398 785) -9)))
+ (xx (math-add x
+ (eval-when-compile
+ (math-read-number-simple "-0.785398164"))))
(a1 (math-poly-eval y
- '((float (bigpos 211 887 093 2) -16)
- (float (bigneg 639 370 073 2) -15)
- (float (bigpos 407 510 734 2) -14)
- (float (bigneg 627 628 098 1) -12)
- (float 1 0))))
+ (eval-when-compile
+ (list
+ (math-read-number-simple "0.0000002093887211")
+ (math-read-number-simple "-0.000002073370639")
+ (math-read-number-simple "0.00002734510407")
+ (math-read-number-simple "-0.001098628627")
+ '(float 1 0)))))
(a2 (math-poly-eval y
- '((float (bigneg 152 935 934) -16)
- (float (bigpos 161 095 621 7) -16)
- (float (bigneg 651 147 911 6) -15)
- (float (bigpos 765 488 430 1) -13)
- (float (bigneg 995 499 562 1) -11))))
+ (eval-when-compile
+ (list
+ (math-read-number-simple "-0.0000000934935152")
+ (math-read-number-simple "0.0000007621095161")
+ (math-read-number-simple "-0.000006911147651")
+ (math-read-number-simple "0.0001430488765")
+ (math-read-number-simple "-0.01562499995")))))
(sc (math-sin-cos-raw xx)))
(if yflag
(setq sc (cons (math-neg (cdr sc)) (car sc))))
(math-mul (math-sqrt
- (math-div '(float (bigpos 722 619 636) -9) x))
+ (math-div (eval-when-compile
+ (math-read-number-simple "0.636619722"))
+ x))
(math-sub (math-mul (cdr sc) a1)
(math-mul (car sc) (math-mul z a2))))))
(t
(let ((y (math-sqr x)))
(math-div (math-poly-eval y
- '((float (bigneg 456 052 849 1) -7)
- (float (bigpos 017 233 739 7) -5)
- (float (bigneg 418 442 121 1) -2)
- (float (bigpos 407 196 516 6) -1)
- (float (bigneg 354 590 362 13) 0)
- (float (bigpos 574 490 568 57) 0)))
+ (eval-when-compile
+ (list
+ (math-read-number-simple "-184.9052456")
+ (math-read-number-simple "77392.33017")
+ (math-read-number-simple "-11214424.18")
+ (math-read-number-simple "651619640.7")
+ (math-read-number-simple "-13362590354.0")
+ (math-read-number-simple "57568490574.0"))))
(math-poly-eval y
- '((float 1 0)
- (float (bigpos 712 532 678 2) -7)
- (float (bigpos 853 264 927 5) -5)
- (float (bigpos 718 680 494 9) -3)
- (float (bigpos 985 532 029 1) 0)
- (float (bigpos 411 490 568 57) 0))))))))
+ (eval-when-compile
+ (list
+ '(float 1 0)
+ (math-read-number-simple "267.8532712")
+ (math-read-number-simple "59272.64853")
+ (math-read-number-simple "9494680.718")
+ (math-read-number-simple "1029532985.0")
+ (math-read-number-simple "57568490411.0")))))))))
(defun math-besJ1 (x &optional yflag)
(cond ((and (math-negp (calcFunc-re x)) (not yflag))
@@ -610,25 +623,33 @@
((Math-lessp '(float 8 0) (math-abs-approx x))
(let* ((z (math-div '(float 8 0) x))
(y (math-sqr z))
- (xx (math-add x '(float (bigneg 491 194 356 2) -9)))
+ (xx (math-add x (eval-when-compile
+ (math-read-number-simple "-2.356194491"))))
(a1 (math-poly-eval y
- '((float (bigneg 019 337 240) -15)
- (float (bigpos 174 520 457 2) -15)
- (float (bigneg 496 396 516 3) -14)
- (float 183105 -8)
- (float 1 0))))
+ (eval-when-compile
+ (list
+ (math-read-number-simple "-0.000000240337019")
+ (math-read-number-simple "0.000002457520174")
+ (math-read-number-simple "-0.00003516396496")
+ '(float 183105 -8)
+ '(float 1 0)))))
(a2 (math-poly-eval y
- '((float (bigpos 412 787 105) -15)
- (float (bigneg 987 228 88) -14)
- (float (bigpos 096 199 449 8) -15)
- (float (bigneg 873 690 002 2) -13)
- (float (bigpos 995 499 687 4) -11))))
+ (eval-when-compile
+ (list
+ (math-read-number-simple "0.000000105787412")
+ (math-read-number-simple "-0.00000088228987")
+ (math-read-number-simple "0.000008449199096")
+ (math-read-number-simple "-0.0002002690873")
+ (math-read-number-simple "0.04687499995")))))
(sc (math-sin-cos-raw xx)))
(if yflag
(setq sc (cons (math-neg (cdr sc)) (car sc)))
(if (math-negp x)
(setq sc (cons (math-neg (car sc)) (math-neg (cdr sc))))))
- (math-mul (math-sqrt (math-div '(float (bigpos 722 619 636) -9) x))
+ (math-mul (math-sqrt (math-div
+ (eval-when-compile
+ (math-read-number-simple "0.636619722"))
+ x))
(math-sub (math-mul (cdr sc) a1)
(math-mul (car sc) (math-mul z a2))))))
(t
@@ -636,20 +657,23 @@
(math-mul
x
(math-div (math-poly-eval y
- '((float (bigneg 606 036 016 3) -8)
- (float (bigpos 826 044 157) -4)
- (float (bigneg 439 611 972 2) -3)
- (float (bigpos 531 968 423 2) -1)
- (float (bigneg 235 059 895 7) 0)
- (float (bigpos 232 614 362 72) 0)))
+ (eval-when-compile
+ (list
+ (math-read-number-simple "-30.16036606")
+ (math-read-number-simple "15704.4826")
+ (math-read-number-simple "-2972611.439")
+ (math-read-number-simple "242396853.1")
+ (math-read-number-simple "-7895059235.0")
+ (math-read-number-simple "72362614232.0"))))
(math-poly-eval y
- '((float 1 0)
- (float (bigpos 397 991 769 3) -7)
- (float (bigpos 394 743 944 9) -5)
- (float (bigpos 474 330 858 1) -2)
- (float (bigpos 178 535 300 2) 0)
- (float (bigpos 442 228 725 144)
- 0)))))))))
+ (eval-when-compile
+ (list
+ '(float 1 0)
+ (math-read-number-simple "376.9991397")
+ (math-read-number-simple "99447.43394")
+ (math-read-number-simple "18583304.74")
+ (math-read-number-simple "2300535178.0")
+ (math-read-number-simple "144725228442.0"))))))))))
(defun calcFunc-besY (v x)
(math-inexact-result)
@@ -690,20 +714,25 @@
(let ((y (math-sqr x)))
(math-add
(math-div (math-poly-eval y
- '((float (bigpos 733 622 284 2) -7)
- (float (bigneg 757 792 632 8) -5)
- (float (bigpos 129 988 087 1) -2)
- (float (bigneg 036 598 123 5) -1)
- (float (bigpos 065 834 062 7) 0)
- (float (bigneg 389 821 957 2) 0)))
+ (eval-when-compile
+ (list
+ (math-read-number-simple "228.4622733")
+ (math-read-number-simple "-86327.92757")
+ (math-read-number-simple "10879881.29")
+ (math-read-number-simple "-512359803.6")
+ (math-read-number-simple "7062834065.0")
+ (math-read-number-simple "-2957821389.0"))))
(math-poly-eval y
- '((float 1 0)
- (float (bigpos 244 030 261 2) -7)
- (float (bigpos 647 472 474) -4)
- (float (bigpos 438 466 189 7) -3)
- (float (bigpos 648 499 452 7) -1)
- (float (bigpos 269 544 076 40) 0))))
- (math-mul '(float (bigpos 772 619 636) -9)
+ (eval-when-compile
+ (list
+ '(float 1 0)
+ (math-read-number-simple "226.1030244")
+ (math-read-number-simple "47447.2647")
+ (math-read-number-simple "7189466.438")
+ (math-read-number-simple "745249964.8")
+ (math-read-number-simple "40076544269.0")))))
+ (math-mul (eval-when-compile
+ (math-read-number-simple "0.636619772"))
(math-mul (math-besJ0 x) (math-ln-raw x))))))
((math-negp (calcFunc-re x))
(math-add (math-besJ0 (math-neg x) t)
@@ -719,22 +748,26 @@
(math-mul
x
(math-div (math-poly-eval y
- '((float (bigpos 935 937 511 8) -6)
- (float (bigneg 726 922 237 4) -3)
- (float (bigpos 551 264 349 7) -1)
- (float (bigneg 139 438 153 5) 1)
- (float (bigpos 439 527 127) 4)
- (float (bigneg 943 604 900 4) 3)))
+ (eval-when-compile
+ (list
+ (math-read-number-simple "8511.937935")
+ (math-read-number-simple "-4237922.726")
+ (math-read-number-simple "734926455.1")
+ (math-read-number-simple "-51534381390.0")
+ (math-read-number-simple "1275274390000.0")
+ (math-read-number-simple "-4900604943000.0"))))
(math-poly-eval y
- '((float 1 0)
- (float (bigpos 885 632 549 3) -7)
- (float (bigpos 605 042 102) -3)
- (float (bigpos 002 904 245 2) -2)
- (float (bigpos 367 650 733 3) 0)
- (float (bigpos 664 419 244 4) 2)
- (float (bigpos 057 958 249) 5)))))
- (math-mul '(float (bigpos 772 619 636) -9)
- (math-sub (math-mul (math-besJ1 x) (math-ln-raw x))
+ (eval-when-compile
+ (list
+ '(float 1 0)
+ (math-read-number-simple "354.9632885")
+ (math-read-number-simple "102042.605")
+ (math-read-number-simple "22459040.02")
+ (math-read-number-simple "3733650367.0")
+ (math-read-number-simple "424441966400.0")
+ (math-read-number-simple "24995805700000.0"))))))
+ (math-mul (eval-when-compile (math-read-number-simple "0.636619772"))
+ (math-sub (math-mul (math-besJ1 x) (math-ln-raw x))
(math-div 1 x))))))
((math-negp (calcFunc-re x))
(math-neg
@@ -799,16 +832,40 @@
(calcFunc-euler n '(float 5 -1)))
(calcFunc-euler n '(frac 1 2))))))
-(defvar math-bernoulli-b-cache '((frac -174611
- (bigpos 0 200 291 698 662 857 802))
- (frac 43867 (bigpos 0 944 170 217 94 109 5))
- (frac -3617 (bigpos 0 880 842 622 670 10))
- (frac 1 (bigpos 600 249 724 74))
- (frac -691 (bigpos 0 368 674 307 1))
- (frac 1 (bigpos 160 900 47))
- (frac -1 (bigpos 600 209 1))
- (frac 1 30240) (frac -1 720)
- (frac 1 12) 1 ))
+(defvar math-bernoulli-b-cache
+ (eval-when-compile
+ (list
+ (list 'frac
+ -174611
+ (math-read-number-simple "802857662698291200000"))
+ (list 'frac
+ 43867
+ (math-read-number-simple "5109094217170944000"))
+ (list 'frac
+ -3617
+ (math-read-number-simple "10670622842880000"))
+ (list 'frac
+ 1
+ (math-read-number-simple "74724249600"))
+ (list 'frac
+ -691
+ (math-read-number-simple "1307674368000"))
+ (list 'frac
+ 1
+ (math-read-number-simple "47900160"))
+ (list 'frac
+ -1
+ (math-read-number-simple "1209600"))
+ (list 'frac
+ 1
+ 30240)
+ (list 'frac
+ -1
+ 720)
+ (list 'frac
+ 1
+ 12)
+ 1 )))
(defvar math-bernoulli-B-cache '((frac -174611 330) (frac 43867 798)
(frac -3617 510) (frac 7 6) (frac -691 2730)
diff --git a/lisp/calc/calc-lang.el b/lisp/calc/calc-lang.el
index 79c33b473c3..c009dbe18aa 100644
--- a/lisp/calc/calc-lang.el
+++ b/lisp/calc/calc-lang.el
@@ -35,7 +35,7 @@
;;; Alternate entry/display languages.
(defun calc-set-language (lang &optional option no-refresh)
- (setq math-expr-opers (or (get lang 'math-oper-table) math-standard-opers)
+ (setq math-expr-opers (or (get lang 'math-oper-table) (math-standard-ops))
math-expr-function-mapping (get lang 'math-function-table)
math-expr-special-function-mapping (get lang 'math-special-function-table)
math-expr-variable-mapping (get lang 'math-variable-table)
@@ -1225,7 +1225,7 @@
h (1+ v) (1+ h) math-rb-v2)
(string-match "<=\\|>=\\|\\+/-\\|!=\\|&&\\|||\\|:=\\|=>\\|." line h)
(assoc (math-match-substring line 0)
- math-standard-opers)))
+ (math-standard-ops))))
(and (>= (nth 2 widest) prec)
(setq h (match-end 0)))
(and (not (eq (string-match ",\\|;\\|\\.\\.\\|)\\|\\]\\|:" line h)
diff --git a/lisp/calc/calc-math.el b/lisp/calc/calc-math.el
index b6481d30b73..d8de812421f 100644
--- a/lisp/calc/calc-math.el
+++ b/lisp/calc/calc-math.el
@@ -310,15 +310,15 @@
(let* ((top (nthcdr (- len 2) a)))
(math-isqrt-bignum-iter
a
- (math-scale-bignum-3
+ (math-scale-bignum-digit-size
(math-bignum-big
(1+ (math-isqrt-small
- (+ (* (nth 1 top) 1000) (car top)))))
+ (+ (* (nth 1 top) math-bignum-digit-size) (car top)))))
(1- (/ len 2)))))
(let* ((top (nth (1- len) a)))
(math-isqrt-bignum-iter
a
- (math-scale-bignum-3
+ (math-scale-bignum-digit-size
(list (1+ (math-isqrt-small top)))
(/ len 2)))))))
@@ -341,14 +341,15 @@
(while (eq (car (setq a (cdr a))) 0))
(null a))))
-(defun math-scale-bignum-3 (a n) ; [L L S]
+(defun math-scale-bignum-digit-size (a n) ; [L L S]
(while (> n 0)
(setq a (cons 0 a)
n (1- n)))
a)
(defun math-isqrt-small (a) ; A > 0. [S S]
- (let ((g (cond ((>= a 10000) 1000)
+ (let ((g (cond ((>= a 1000000) 10000)
+ ((>= a 10000) 1000)
((>= a 100) 100)
(t 10)))
g2)
@@ -1717,10 +1718,20 @@
sum
(math-lnp1-series nextsum (1+ n) nextx x))))
-(math-defcache math-ln-10 (float (bigpos 018 684 045 994 092 585 302 2) -21)
+(defconst math-approx-ln-10
+ (eval-when-compile
+ (math-read-number-simple "2.302585092994045684018"))
+ "An approximation for ln(10).")
+
+(math-defcache math-ln-10 math-approx-ln-10
(math-ln-raw-2 '(float 1 1)))
-(math-defcache math-ln-2 (float (bigpos 417 309 945 559 180 147 693) -21)
+(defconst math-approx-ln-2
+ (eval-when-compile
+ (math-read-number-simple "0.693147180559945309417"))
+ "An approximation for ln(2).")
+
+(math-defcache math-ln-2 math-approx-ln-2
(math-ln-raw-3 (math-float '(frac 1 3))))
diff --git a/lisp/calc/calc-misc.el b/lisp/calc/calc-misc.el
index e9674ff938b..ecc304a5f5f 100644
--- a/lisp/calc/calc-misc.el
+++ b/lisp/calc/calc-misc.el
@@ -579,7 +579,7 @@ loaded and the keystroke automatically re-typed."
(defun math-div2-bignum (a) ; [l l]
(if (cdr a)
- (cons (+ (/ (car a) 2) (* (% (nth 1 a) 2) 500))
+ (cons (+ (/ (car a) 2) (* (% (nth 1 a) 2) (/ math-bignum-digit-size 2)))
(math-div2-bignum (cdr a)))
(list (/ (car a) 2))))
diff --git a/lisp/calc/calc-poly.el b/lisp/calc/calc-poly.el
index 0bcf78af861..23000888749 100644
--- a/lisp/calc/calc-poly.el
+++ b/lisp/calc/calc-poly.el
@@ -982,10 +982,16 @@
(defun math-padded-polynomial (expr var deg)
+ "Return a polynomial as list of coefficients.
+If EXPR is of the form \"a + bx + cx^2 + ...\" in the variable VAR, return
+the list (a b c ...) with at least DEG elements, else return NIL."
(let ((p (math-is-polynomial expr var deg)))
(append p (make-list (- deg (length p)) 0))))
(defun math-partial-fractions (r den var)
+ "Return R divided by DEN expressed in partial fractions of VAR.
+All whole factors of DEN have already been split off from R.
+If no partial fraction representation can be found, return nil."
(let* ((fden (calcFunc-factors den var))
(tdeg (math-polynomial-p den var))
(fp fden)
diff --git a/lisp/calc/calc-prog.el b/lisp/calc/calc-prog.el
index 4dff6f04013..cacad666772 100644
--- a/lisp/calc/calc-prog.el
+++ b/lisp/calc/calc-prog.el
@@ -568,7 +568,7 @@
(set-buffer calc-buf)
(let ((calc-user-parse-tables nil)
(calc-language nil)
- (math-expr-opers math-standard-opers)
+ (math-expr-opers (math-standard-ops))
(calc-hashes-used 0))
(math-read-expr
(if (string-match ",[ \t]*\\'" str)
diff --git a/lisp/calc/calc-yank.el b/lisp/calc/calc-yank.el
index abd78e5f926..a872f69d83f 100644
--- a/lisp/calc/calc-yank.el
+++ b/lisp/calc/calc-yank.el
@@ -559,7 +559,7 @@ To cancel the edit, simply kill the *Calc Edit* buffer."
(aset str pos ?\,)))
(switch-to-buffer calc-original-buffer)
(let ((vals (let ((calc-language nil)
- (math-expr-opers math-standard-opers))
+ (math-expr-opers (math-standard-ops)))
(and (string-match "[^\n\t ]" str)
(math-read-exprs str)))))
(when (eq (car-safe vals) 'error)
diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el
index 4ca5662afdc..6a235e42321 100644
--- a/lisp/calc/calc.el
+++ b/lisp/calc/calc.el
@@ -401,6 +401,13 @@ This is not required to be present for user-written mode annotations."
:group 'calc
:type '(choice (string) (sexp)))
+(defcustom calc-multiplication-has-precedence
+ t
+ "*If non-nil, multiplication has precedence over division
+in normal mode."
+ :group 'calc
+ :type 'boolean)
+
(defvar calc-bug-address "jay.p.belanger@gmail.com"
"Address of the maintainer of Calc, for use by `report-calc-bug'.")
@@ -2276,7 +2283,21 @@ See calc-keypad for details."
+(defconst math-bignum-digit-length 4
+; (truncate (/ (log10 (/ most-positive-fixnum 2)) 2))
+ "The length of a \"digit\" in Calc bignums.
+If a big integer is of the form (bigpos N0 N1 ...), this is the
+length of the allowable Emacs integers N0, N1,...
+The value of 2*10^(2*MATH-BIGNUM-DIGIT-LENGTH) must be less than the
+largest Emacs integer.")
+
+(defconst math-bignum-digit-size
+ (expt 10 math-bignum-digit-length)
+ "An upper bound for the size of the \"digit\"s in Calc bignums.")
+(defconst math-small-integer-size
+ (expt math-bignum-digit-size 2)
+ "An upper bound for the size of \"small integer\"s in Calc.")
;;;; Arithmetic routines.
@@ -2285,11 +2306,17 @@ See calc-keypad for details."
;;; following forms:
;;;
;;; integer An integer. For normalized numbers, this format
-;;; is used only for -999999 ... 999999.
+;;; is used only for
+;;; negative math-small-integer-size + 1 to
+;;; math-small-integer-size - 1
;;;
-;;; (bigpos N0 N1 N2 ...) A big positive integer, N0 + N1*1000 + N2*10^6 ...
-;;; (bigneg N0 N1 N2 ...) A big negative integer, - N0 - N1*1000 ...
-;;; Each digit N is in the range 0 ... 999.
+;;; (bigpos N0 N1 N2 ...) A big positive integer,
+;;; N0 + N1*math-bignum-digit-size
+;;; + N2*(math-bignum-digit-size)^2 ...
+;;; (bigneg N0 N1 N2 ...) A big negative integer,
+;;; - N0 - N1*math-bignum-digit-size ...
+;;; Each digit N is in the range
+;;; 0 ... math-bignum-digit-size -1.
;;; Normalized, always at least three N present,
;;; and the most significant N is nonzero.
;;;
@@ -2379,7 +2406,8 @@ See calc-keypad for details."
(cond
((not (consp math-normalize-a))
(if (integerp math-normalize-a)
- (if (or (>= math-normalize-a 1000000) (<= math-normalize-a -1000000))
+ (if (or (>= math-normalize-a math-small-integer-size)
+ (<= math-normalize-a (- math-small-integer-size)))
(math-bignum math-normalize-a)
math-normalize-a)
math-normalize-a))
@@ -2394,7 +2422,8 @@ See calc-keypad for details."
math-normalize-a
(cond
((cdr (cdr math-normalize-a)) (+ (nth 1 math-normalize-a)
- (* (nth 2 math-normalize-a) 1000)))
+ (* (nth 2 math-normalize-a)
+ math-bignum-digit-size)))
((cdr math-normalize-a) (nth 1 math-normalize-a))
(t 0))))
((eq (car math-normalize-a) 'bigneg)
@@ -2408,7 +2437,8 @@ See calc-keypad for details."
math-normalize-a
(cond
((cdr (cdr math-normalize-a)) (- (+ (nth 1 math-normalize-a)
- (* (nth 2 math-normalize-a) 1000))))
+ (* (nth 2 math-normalize-a)
+ math-bignum-digit-size))))
((cdr math-normalize-a) (- (nth 1 math-normalize-a)))
(t 0))))
((eq (car math-normalize-a) 'float)
@@ -2528,7 +2558,8 @@ See calc-keypad for details."
(defun math-bignum-big (a) ; [L s]
(if (= a 0)
nil
- (cons (% a 1000) (math-bignum-big (/ a 1000)))))
+ (cons (% a math-bignum-digit-size)
+ (math-bignum-big (/ a math-bignum-digit-size)))))
;;; Build a normalized floating-point number. [F I S]
@@ -2545,7 +2576,7 @@ See calc-keypad for details."
(progn
(while (= (car digs) 0)
(setq digs (cdr digs)
- exp (+ exp 3)))
+ exp (+ exp math-bignum-digit-length)))
(while (= (% (car digs) 10) 0)
(setq digs (math-div10-bignum digs)
exp (1+ exp)))
@@ -2563,7 +2594,8 @@ See calc-keypad for details."
(defun math-div10-bignum (a) ; [l l]
(if (cdr a)
- (cons (+ (/ (car a) 10) (* (% (nth 1 a) 10) 100))
+ (cons (+ (/ (car a) 10) (* (% (nth 1 a) 10)
+ (expt 10 (1- math-bignum-digit-length))))
(math-div10-bignum (cdr a)))
(list (/ (car a) 10))))
@@ -2594,7 +2626,7 @@ See calc-keypad for details."
(if (cdr a)
(let* ((len (1- (length a)))
(top (nth len a)))
- (+ (* len 3) (cond ((>= top 100) 0) ((>= top 10) -1) (t -2))))
+ (+ (* (1- len) math-bignum-digit-length) (math-numdigs top)))
0)
(cond ((>= a 100) (+ (math-numdigs (/ a 1000)) 3))
((>= a 10) 2)
@@ -2615,24 +2647,24 @@ See calc-keypad for details."
a
(if (consp a)
(cons (car a) (math-scale-left-bignum (cdr a) n))
- (if (>= n 3)
- (if (or (>= a 1000) (<= a -1000))
+ (if (>= n math-bignum-digit-length)
+ (if (or (>= a math-bignum-digit-size)
+ (<= a (- math-bignum-digit-size)))
(math-scale-left (math-bignum a) n)
- (math-scale-left (* a 1000) (- n 3)))
- (if (= n 2)
- (if (or (>= a 10000) (<= a -10000))
- (math-scale-left (math-bignum a) 2)
- (* a 100))
- (if (or (>= a 100000) (<= a -100000))
- (math-scale-left (math-bignum a) 1)
- (* a 10)))))))
+ (math-scale-left (* a math-bignum-digit-size)
+ (- n math-bignum-digit-length)))
+ (let ((sz (expt 10 (- (* 2 math-bignum-digit-length) n))))
+ (if (or (>= a sz) (<= a (- sz)))
+ (math-scale-left (math-bignum a) n)
+ (* a (expt 10 n))))))))
(defun math-scale-left-bignum (a n)
- (if (>= n 3)
+ (if (>= n math-bignum-digit-length)
(while (>= (setq a (cons 0 a)
- n (- n 3)) 3)))
+ n (- n math-bignum-digit-length))
+ math-bignum-digit-length)))
(if (> n 0)
- (math-mul-bignum-digit a (if (= n 2) 100 10) 0)
+ (math-mul-bignum-digit a (expt 10 n) 0)
a))
(defun math-scale-right (a n) ; [i i S]
@@ -2644,21 +2676,20 @@ See calc-keypad for details."
(if (= a 0)
0
(- (math-scale-right (- a) n)))
- (if (>= n 3)
- (while (and (> (setq a (/ a 1000)) 0)
- (>= (setq n (- n 3)) 3))))
- (if (= n 2)
- (/ a 100)
- (if (= n 1)
- (/ a 10)
- a))))))
+ (if (>= n math-bignum-digit-length)
+ (while (and (> (setq a (/ a math-bignum-digit-size)) 0)
+ (>= (setq n (- n math-bignum-digit-length))
+ math-bignum-digit-length))))
+ (if (> n 0)
+ (/ a (expt 10 n))
+ a)))))
(defun math-scale-right-bignum (a n) ; [L L S; l l S]
- (if (>= n 3)
- (setq a (nthcdr (/ n 3) a)
- n (% n 3)))
+ (if (>= n math-bignum-digit-length)
+ (setq a (nthcdr (/ n math-bignum-digit-length) a)
+ n (% n math-bignum-digit-length)))
(if (> n 0)
- (cdr (math-mul-bignum-digit a (if (= n 2) 10 100) 0))
+ (cdr (math-mul-bignum-digit a (expt 10 (- math-bignum-digit-length n)) 0))
a))
;;; Multiply (with rounding) the integer A by 10^N. [I i S]
@@ -2668,16 +2699,18 @@ See calc-keypad for details."
((consp a)
(math-normalize
(cons (car a)
- (let ((val (if (< n -3)
- (math-scale-right-bignum (cdr a) (- -3 n))
- (if (= n -2)
- (math-mul-bignum-digit (cdr a) 10 0)
- (if (= n -1)
- (math-mul-bignum-digit (cdr a) 100 0)
- (cdr a)))))) ; n = -3
- (if (and val (>= (car val) 500))
+ (let ((val (if (< n (- math-bignum-digit-length))
+ (math-scale-right-bignum
+ (cdr a)
+ (- (- math-bignum-digit-length) n))
+ (if (< n 0)
+ (math-mul-bignum-digit
+ (cdr a)
+ (expt 10 (+ math-bignum-digit-length n)) 0)
+ (cdr a))))) ; n = -math-bignum-digit-length
+ (if (and val (>= (car val) (/ math-bignum-digit-size 2)))
(if (cdr val)
- (if (eq (car (cdr val)) 999)
+ (if (eq (car (cdr val)) (1- math-bignum-digit-size))
(math-add-bignum (cdr val) '(1))
(cons (1+ (car (cdr val))) (cdr (cdr val))))
'(1))
@@ -2696,7 +2729,7 @@ See calc-keypad for details."
(and (not (or (consp a) (consp b)))
(progn
(setq a (+ a b))
- (if (or (<= a -1000000) (>= a 1000000))
+ (if (or (<= a (- math-small-integer-size)) (>= a math-small-integer-size))
(math-bignum a)
a)))
(and (Math-zerop a) (not (eq (car-safe a) 'mod))
@@ -2745,21 +2778,22 @@ See calc-keypad for details."
(let* ((a (copy-sequence a)) (aa a) (carry nil) sum)
(while (and aa b)
(if carry
- (if (< (setq sum (+ (car aa) (car b))) 999)
+ (if (< (setq sum (+ (car aa) (car b)))
+ (1- math-bignum-digit-size))
(progn
(setcar aa (1+ sum))
(setq carry nil))
- (setcar aa (+ sum -999)))
- (if (< (setq sum (+ (car aa) (car b))) 1000)
+ (setcar aa (- sum (1- math-bignum-digit-size))))
+ (if (< (setq sum (+ (car aa) (car b))) math-bignum-digit-size)
(setcar aa sum)
- (setcar aa (+ sum -1000))
+ (setcar aa (- sum math-bignum-digit-size))
(setq carry t)))
(setq aa (cdr aa)
b (cdr b)))
(if carry
(if b
(nconc a (math-add-bignum b '(1)))
- (while (eq (car aa) 999)
+ (while (eq (car aa) (1- math-bignum-digit-size))
(setcar aa 0)
(setq aa (cdr aa)))
(if aa
@@ -2783,17 +2817,17 @@ See calc-keypad for details."
(progn
(setcar aa (1- diff))
(setq borrow nil))
- (setcar aa (+ diff 999)))
+ (setcar aa (+ diff (1- math-bignum-digit-size))))
(if (>= (setq diff (- (car aa) (car b))) 0)
(setcar aa diff)
- (setcar aa (+ diff 1000))
+ (setcar aa (+ diff math-bignum-digit-size))
(setq borrow t)))
(setq aa (cdr aa)
b (cdr b)))
(if borrow
(progn
(while (eq (car aa) 0)
- (setcar aa 999)
+ (setcar aa (1- math-bignum-digit-size))
(setq aa (cdr aa)))
(if aa
(progn
@@ -2833,7 +2867,7 @@ See calc-keypad for details."
(if (or (consp a) (consp b))
(math-add a (math-neg b))
(setq a (- a b))
- (if (or (<= a -1000000) (>= a 1000000))
+ (if (or (<= a (- math-small-integer-size)) (>= a math-small-integer-size))
(math-bignum a)
a)))
@@ -2860,7 +2894,8 @@ See calc-keypad for details."
(defun math-mul (a b)
(or
(and (not (consp a)) (not (consp b))
- (< a 1000) (> a -1000) (< b 1000) (> b -1000)
+ (< a math-bignum-digit-size) (> a (- math-bignum-digit-size))
+ (< b math-bignum-digit-size) (> b (- math-bignum-digit-size))
(* a b))
(and (Math-zerop a) (not (eq (car-safe b) 'mod))
(if (Math-scalarp b)
@@ -2929,14 +2964,14 @@ See calc-keypad for details."
aa a)
(while (progn
(setcar ss (% (setq prod (+ (+ (car ss) (* (car aa) d))
- c)) 1000))
+ c)) math-bignum-digit-size))
(setq aa (cdr aa)))
- (setq c (/ prod 1000)
+ (setq c (/ prod math-bignum-digit-size)
ss (or (cdr ss) (setcdr ss (list 0)))))
- (if (>= prod 1000)
+ (if (>= prod math-bignum-digit-size)
(if (cdr ss)
- (setcar (cdr ss) (+ (/ prod 1000) (car (cdr ss))))
- (setcdr ss (list (/ prod 1000))))))
+ (setcar (cdr ss) (+ (/ prod math-bignum-digit-size) (car (cdr ss))))
+ (setcdr ss (list (/ prod math-bignum-digit-size))))))
sum)))
;;; Multiply digit list A by digit D. [L L D D; l l D D]
@@ -2946,12 +2981,14 @@ See calc-keypad for details."
(and (= d 1) a)
(let* ((a (copy-sequence a)) (aa a) prod)
(while (progn
- (setcar aa (% (setq prod (+ (* (car aa) d) c)) 1000))
+ (setcar aa
+ (% (setq prod (+ (* (car aa) d) c))
+ math-bignum-digit-size))
(cdr aa))
(setq aa (cdr aa)
- c (/ prod 1000)))
- (if (>= prod 1000)
- (setcdr aa (list (/ prod 1000))))
+ c (/ prod math-bignum-digit-size)))
+ (if (>= prod math-bignum-digit-size)
+ (setcdr aa (list (/ prod math-bignum-digit-size))))
a))
(and (> c 0)
(list c))))
@@ -2964,7 +3001,7 @@ See calc-keypad for details."
(if (eq b 0)
(math-reject-arg a "*Division by zero"))
(if (or (consp a) (consp b))
- (if (and (natnump b) (< b 1000))
+ (if (and (natnump b) (< b math-bignum-digit-size))
(let ((res (math-div-bignum-digit (cdr a) b)))
(cons
(math-normalize (cons (car a) (car res)))
@@ -2983,7 +3020,7 @@ See calc-keypad for details."
(if (= b 0)
(math-reject-arg a "*Division by zero")
(/ a b))
- (if (and (natnump b) (< b 1000))
+ (if (and (natnump b) (< b math-bignum-digit-size))
(if (= b 0)
(math-reject-arg a "*Division by zero")
(math-normalize (cons (car a)
@@ -2992,7 +3029,7 @@ See calc-keypad for details."
(or (consp b) (setq b (math-bignum b)))
(let* ((alen (1- (length a)))
(blen (1- (length b)))
- (d (/ 1000 (1+ (nth (1- blen) (cdr b)))))
+ (d (/ math-bignum-digit-size (1+ (nth (1- blen) (cdr b)))))
(res (math-div-bignum-big (math-mul-bignum-digit (cdr a) d 0)
(math-mul-bignum-digit (cdr b) d 0)
alen blen)))
@@ -3006,7 +3043,7 @@ See calc-keypad for details."
(if (cdr b)
(let* ((alen (length a))
(blen (length b))
- (d (/ 1000 (1+ (nth (1- blen) b))))
+ (d (/ math-bignum-digit-size (1+ (nth (1- blen) b))))
(res (math-div-bignum-big (math-mul-bignum-digit a d 0)
(math-mul-bignum-digit b d 0)
alen blen)))
@@ -3021,7 +3058,7 @@ See calc-keypad for details."
(defun math-div-bignum-digit (a b)
(if a
(let* ((res (math-div-bignum-digit (cdr a) b))
- (num (+ (* (cdr res) 1000) (car a))))
+ (num (+ (* (cdr res) math-bignum-digit-size) (car a))))
(cons
(cons (/ num b) (car res))
(% num b)))
@@ -3037,10 +3074,11 @@ See calc-keypad for details."
(cons (car res2) (car res))
(cdr res2)))))
-(defun math-div-bignum-part (a b blen) ; a < b*1000 [D.l l L]
- (let* ((num (+ (* (or (nth blen a) 0) 1000) (or (nth (1- blen) a) 0)))
+(defun math-div-bignum-part (a b blen) ; a < b*math-bignum-digit-size [D.l l L]
+ (let* ((num (+ (* (or (nth blen a) 0) math-bignum-digit-size)
+ (or (nth (1- blen) a) 0)))
(den (nth (1- blen) b))
- (guess (min (/ num den) 999)))
+ (guess (min (/ num den) (1- math-bignum-digit-size))))
(math-div-bignum-try a b (math-mul-bignum-digit b guess 0) guess)))
(defun math-div-bignum-try (a b c guess) ; [D.l l l D]
@@ -3351,15 +3389,22 @@ See calc-keypad for details."
(if a
(let ((s ""))
(while (cdr (cdr a))
- (setq s (concat (format "%06d" (+ (* (nth 1 a) 1000) (car a))) s)
+ (setq s (concat
+ (format
+ (concat "%0"
+ (number-to-string (* 2 math-bignum-digit-length))
+ "d")
+ (+ (* (nth 1 a) math-bignum-digit-size) (car a))) s)
a (cdr (cdr a))))
- (concat (int-to-string (+ (* (or (nth 1 a) 0) 1000) (car a))) s))
+ (concat (int-to-string
+ (+ (* (or (nth 1 a) 0) math-bignum-digit-size) (car a))) s))
"0"))
;;; Parse a simple number in string form. [N X] [Public]
(defun math-read-number (s)
+ "Convert the string S into a Calc number."
(math-normalize
(cond
@@ -3370,7 +3415,7 @@ See calc-keypad for details."
(> (length digs) 1)
(eq (aref digs 0) ?0))
(math-read-number (concat "8#" digs))
- (if (<= (length digs) 6)
+ (if (<= (length digs) (* 2 math-bignum-digit-length))
(string-to-number digs)
(cons 'bigpos (math-read-bignum digs))))))
@@ -3416,15 +3461,42 @@ See calc-keypad for details."
;; Syntax error!
(t nil))))
+;;; Parse a very simple number, keeping all digits.
+(defun math-read-number-simple (s)
+ "Convert the string S into a Calc number.
+S is assumed to be a simple number (integer or float without an exponent)
+and all digits are kept, regardless of Calc's current precision."
+ (cond
+ ;; Integer
+ ((string-match "^[0-9]+$" s)
+ (if (string-match "^\\(0+\\)" s)
+ (setq s (substring s (match-end 0))))
+ (if (<= (length s) (* 2 math-bignum-digit-length))
+ (string-to-number s)
+ (cons 'bigpos (math-read-bignum s))))
+ ;; Minus sign
+ ((string-match "^-[0-9]+$" s)
+ (if (<= (length s) (1+ (* 2 math-bignum-digit-length)))
+ (string-to-number s)
+ (cons 'bigneg (math-read-bignum (substring s 1)))))
+ ;; Decimal point
+ ((string-match "^\\(-?[0-9]*\\)\\.\\([0-9]*\\)$" s)
+ (let ((int (math-match-substring s 1))
+ (frac (math-match-substring s 2)))
+ (list 'float (math-read-number-simple (concat int frac))
+ (- (length frac)))))
+ ;; Syntax error!
+ (t nil)))
+
(defun math-match-substring (s n)
(if (match-beginning n)
(substring s (match-beginning n) (match-end n))
""))
(defun math-read-bignum (s) ; [l X]
- (if (> (length s) 3)
- (cons (string-to-number (substring s -3))
- (math-read-bignum (substring s 0 -3)))
+ (if (> (length s) math-bignum-digit-length)
+ (cons (string-to-number (substring s (- math-bignum-digit-length)))
+ (math-read-bignum (substring s 0 (- math-bignum-digit-length))))
(list (string-to-number s))))
@@ -3467,8 +3539,6 @@ See calc-keypad for details."
( "!" calcFunc-fact 210 -1 )
( "^" ^ 201 200 )
( "**" ^ 201 200 )
- ( "*" * 196 195 )
- ( "2x" * 196 195 )
( "/" / 190 191 )
( "%" % 190 191 )
( "\\" calcFunc-idiv 190 191 )
@@ -3492,7 +3562,31 @@ See calc-keypad for details."
( "::" calcFunc-condition 45 46 )
( "=>" calcFunc-evalto 40 41 )
( "=>" calcFunc-evalto 40 -1 )))
-(defvar math-expr-opers math-standard-opers)
+
+(defun math-standard-ops ()
+ (if calc-multiplication-has-precedence
+ (cons
+ '( "*" * 196 195 )
+ (cons
+ '( "2x" * 196 195 )
+ math-standard-opers))
+ (cons
+ '( "*" * 190 191 )
+ (cons
+ '( "2x" * 190 191 )
+ math-standard-opers))))
+
+(defvar math-expr-opers (math-standard-ops))
+
+(defun math-standard-ops-p ()
+ (let ((meo (caar math-expr-opers)))
+ (and (stringp meo)
+ (string= meo "*"))))
+
+(defun math-expr-ops ()
+ (if (math-standard-ops-p)
+ (math-standard-ops)
+ math-expr-opers))
;;;###autoload
(defun calc-grab-region (top bot arg)
diff --git a/lisp/calc/calccomp.el b/lisp/calc/calccomp.el
index 7b385261735..3b52edecaec 100644
--- a/lisp/calc/calccomp.el
+++ b/lisp/calc/calccomp.el
@@ -83,6 +83,7 @@
(defun math-compose-expr (a prec)
(let ((math-compose-level (1+ math-compose-level))
+ (math-expr-opers (math-expr-ops))
spfn)
(cond
((or (and (eq a math-comp-selected) a)