summaryrefslogtreecommitdiff
path: root/lisp/calc/calc.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/calc/calc.el')
-rw-r--r--lisp/calc/calc.el566
1 files changed, 46 insertions, 520 deletions
diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el
index 2136a099eed..3a9a2804cf2 100644
--- a/lisp/calc/calc.el
+++ b/lisp/calc/calc.el
@@ -211,7 +211,6 @@
(declare-function math-group-float "calc-ext" (str))
(declare-function math-mod "calc-misc" (a b))
(declare-function math-format-number-fancy "calc-ext" (a prec))
-(declare-function math-format-bignum-fancy "calc-ext" (a))
(declare-function math-read-number-fancy "calc-ext" (s))
(declare-function calc-do-grab-region "calc-yank" (top bot arg))
(declare-function calc-do-grab-rectangle "calc-yank" (top bot arg &optional reduce))
@@ -232,7 +231,6 @@
(defcustom calc-settings-file
(locate-user-emacs-file "calc.el" ".calc.el")
"File in which to record permanent settings."
- :group 'calc
:type '(file))
(defcustom calc-language-alist
@@ -248,14 +246,12 @@
(f90-mode . fortran)
(texinfo-mode . calc-normal-language))
"Alist of major modes with appropriate Calc languages."
- :group 'calc
:type '(alist :key-type (symbol :tag "Major mode")
:value-type (symbol :tag "Calc language")))
(defcustom calc-embedded-announce-formula
"%Embed\n\\(% .*\n\\)*"
"A regular expression which is sure to be followed by a calc-embedded formula."
- :group 'calc
:type '(regexp))
(defcustom calc-embedded-announce-formula-alist
@@ -271,26 +267,22 @@
(xml-mode . "<!-- Embed -->\n\\(<!-- .* -->\n\\)*")
(texinfo-mode . "@c Embed\n\\(@c .*\n\\)*"))
"Alist of major modes with appropriate values for `calc-embedded-announce-formula'."
- :group 'calc
:type '(alist :key-type (symbol :tag "Major mode")
:value-type (regexp :tag "Regexp to announce formula")))
(defcustom calc-embedded-open-formula
"\\`\\|^\n\\|\\$\\$?\\|\\\\\\[\\|^\\\\begin[^{].*\n\\|^\\\\begin{.*[^x]}.*\n\\|^@.*\n\\|^\\.EQ.*\n\\|\\\\(\\|^%\n\\|^\\.\\\\\"\n"
"A regular expression for the opening delimiter of a formula used by calc-embedded."
- :group 'calc
:type '(regexp))
(defcustom calc-embedded-close-formula
"\\'\\|\n$\\|\\$\\$?\\|\\\\]\\|^\\\\end[^{].*\n\\|^\\\\end{.*[^x]}.*\n\\|^@.*\n\\|^\\.EN.*\n\\|\\\\)\\|\n%\n\\|^\\.\\\\\"\n"
"A regular expression for the closing delimiter of a formula used by calc-embedded."
- :group 'calc
:type '(regexp))
(defcustom calc-embedded-open-close-formula-alist
nil
"Alist of major modes with pairs of formula delimiters used by calc-embedded."
- :group 'calc
:type '(alist :key-type (symbol :tag "Major mode")
:value-type (list (regexp :tag "Opening formula delimiter")
(regexp :tag "Closing formula delimiter"))))
@@ -298,13 +290,11 @@
(defcustom calc-embedded-word-regexp
"[-+]?[0-9]+\\(\\.[0-9]+\\)?\\([eE][-+]?[0-9]+\\)?"
"A regular expression determining a word for calc-embedded-word."
- :group 'calc
:type '(regexp))
(defcustom calc-embedded-word-regexp-alist
nil
"Alist of major modes with word regexps used by calc-embedded-word."
- :group 'calc
:type '(alist :key-type (symbol :tag "Major mode")
:value-type (regexp :tag "Regexp for word")))
@@ -313,14 +303,12 @@
"A string which is the opening delimiter for a \"plain\" formula.
If calc-show-plain mode is enabled, this is inserted at the front of
each formula."
- :group 'calc
:type '(string))
(defcustom calc-embedded-close-plain
" %%%\n"
"A string which is the closing delimiter for a \"plain\" formula.
See calc-embedded-open-plain."
- :group 'calc
:type '(string))
(defcustom calc-embedded-open-close-plain-alist
@@ -336,7 +324,6 @@ See calc-embedded-open-plain."
(xml-mode "<!-- %% " " %% -->\n")
(texinfo-mode "@c %% " " %%\n"))
"Alist of major modes with pairs of delimiters for \"plain\" formulas."
- :group 'calc
:type '(alist :key-type (symbol :tag "Major mode")
:value-type (list (string :tag "Opening \"plain\" delimiter")
(string :tag "Closing \"plain\" delimiter"))))
@@ -344,19 +331,16 @@ See calc-embedded-open-plain."
(defcustom calc-embedded-open-new-formula
"\n\n"
"A string which is inserted at front of formula by calc-embedded-new-formula."
- :group 'calc
:type '(string))
(defcustom calc-embedded-close-new-formula
"\n\n"
"A string which is inserted at end of formula by calc-embedded-new-formula."
- :group 'calc
:type '(string))
(defcustom calc-embedded-open-close-new-formula-alist
nil
"Alist of major modes with pairs of new formula delimiters used by calc-embedded."
- :group 'calc
:type '(alist :key-type (symbol :tag "Major mode")
:value-type (list (string :tag "Opening new formula delimiter")
(string :tag "Closing new formula delimiter"))))
@@ -365,14 +349,12 @@ See calc-embedded-open-plain."
"% "
"A string which should precede calc-embedded mode annotations.
This is not required to be present for user-written mode annotations."
- :group 'calc
:type '(string))
(defcustom calc-embedded-close-mode
"\n"
"A string which should follow calc-embedded mode annotations.
This is not required to be present for user-written mode annotations."
- :group 'calc
:type '(string))
(defcustom calc-embedded-open-close-mode-alist
@@ -388,7 +370,6 @@ This is not required to be present for user-written mode annotations."
(xml-mode "<!-- " " -->\n")
(texinfo-mode "@c " "\n"))
"Alist of major modes with pairs of strings to delimit annotations."
- :group 'calc
:type '(alist :key-type (symbol :tag "Major mode")
:value-type (list (string :tag "Opening annotation delimiter")
(string :tag "Closing annotation delimiter"))))
@@ -402,34 +383,29 @@ This is not required to be present for user-written mode annotations."
"pgnuplot"
"gnuplot")
"Name of GNUPLOT program, for calc-graph features."
- :group 'calc
:type '(string)
:version "26.2")
(defcustom calc-gnuplot-plot-command
nil
"Name of command for displaying GNUPLOT output; %s = file name to print."
- :group 'calc
:type '(choice (string) (sexp)))
(defcustom calc-gnuplot-print-command
"lp %s"
"Name of command for printing GNUPLOT output; %s = file name to print."
- :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)
(defcustom calc-ensure-consistent-units
nil
"If non-nil, make sure new units are consistent with current units
when converting units."
- :group 'calc
:version "24.3"
:type 'boolean)
@@ -437,14 +413,12 @@ when converting units."
nil
"If non-nil, the stack element under the cursor will be copied by `calc-enter'
and deleted by `calc-pop'."
- :group 'calc
:version "24.4"
:type 'boolean)
(defcustom calc-undo-length
100
"The number of undo steps that will be preserved when Calc is quit."
- :group 'calc
:type 'integer)
(defcustom calc-highlight-selections-with-faces
@@ -455,42 +429,36 @@ shown by displaying the rest of the formula in `calc-nonselected-face'.
If option `calc-show-selections' is nil, then selected sub-formulas are shown
by displaying the sub-formula in `calc-selected-face'."
:version "24.1"
- :group 'calc
:type 'boolean)
(defcustom calc-lu-field-reference
"20 uPa"
"The default reference level for logarithmic units (field)."
:version "24.1"
- :group 'calc
:type '(string))
(defcustom calc-lu-power-reference
"mW"
"The default reference level for logarithmic units (power)."
:version "24.1"
- :group 'calc
:type '(string))
(defcustom calc-note-threshold "1"
"The number of cents that a frequency should be near a note
to be identified as that note."
:version "24.1"
- :type 'string
- :group 'calc)
+ :type 'string)
(defvar math-format-date-cache) ; calc-forms.el
(defface calc-nonselected-face
'((t :inherit shadow
:slant italic))
- "Face used to show the non-selected portion of a formula."
- :group 'calc)
+ "Face used to show the non-selected portion of a formula.")
(defface calc-selected-face
'((t :weight bold))
- "Face used to show the selected portion of a formula."
- :group 'calc)
+ "Face used to show the selected portion of a formula.")
(define-obsolete-variable-alias 'calc-bug-address 'report-emacs-bug-address
"26.2")
@@ -934,7 +902,6 @@ Used by `calc-user-invocation'.")
;; The following modes use specially-formatted data.
(put 'calc-mode 'mode-class 'special)
-(put 'calc-trail-mode 'mode-class 'special)
(define-error 'calc-error "Calc internal error")
(define-error 'inexact-result
@@ -1384,7 +1351,7 @@ Notations: 3.14e6 3.14 * 10^6
(set-buffer "*Calculator*")
(while plist
(put 'calc-define (car plist) nil)
- (eval (nth 1 plist))
+ (eval (nth 1 plist) t)
(setq plist (cdr (cdr plist))))
;; See if this has added any more calc-define properties.
(calc-check-defines))
@@ -1410,7 +1377,7 @@ commands given here will actually operate on the *Calculator* stack."
(make-local-variable 'overlay-arrow-position)
(make-local-variable 'overlay-arrow-string)
(when (= (buffer-size) 0)
- (let ((buffer-read-only nil))
+ (let ((inhibit-read-only t))
(insert (propertize "Emacs Calculator Trail\n" 'face 'italic)))))
(defun calc-create-buffer ()
@@ -2043,7 +2010,6 @@ on 15 October 1582 (Gregorian), and many Catholic countries made
the change then. Great Britain and its colonies had the Gregorian
calendar take effect on 14 September 1752 (Gregorian); this includes
the United States."
- :group 'calc
:version "24.4"
:type '(choice (const :tag "Always use the Gregorian calendar" nil)
(const :tag "1582-10-15 - Italy, Poland, Portugal, Spain" (1582 10 15 577736))
@@ -2490,51 +2456,18 @@ the United States."
(setq last-command-event 13)
(calcDigit-nondigit))))
-
-
-
-(defconst math-bignum-digit-length
- (truncate (/ (log (/ most-positive-fixnum 2) 10) 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.
;;
;; An object as manipulated by one of these routines may take any of the
;; following forms:
;;
-;; integer An integer. For normalized numbers, this format
-;; 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*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.
+;; integer An integer.
;;
-;; (frac NUM DEN) A fraction. NUM and DEN are small or big integers.
+;; (frac NUM DEN) A fraction. NUM and DEN are integers.
;; Normalized, DEN > 1.
;;
;; (float NUM EXP) A floating-point number, NUM * 10^EXP;
-;; NUM is a small or big integer, EXP is a small int.
+;; NUM and EXP are integers.
;; Normalized, NUM is not a multiple of 10, and
;; abs(NUM) < 10^calc-internal-prec.
;; Normalized zero is stored as (float 0 0).
@@ -2595,8 +2528,7 @@ largest Emacs integer.")
;; B Normalized big integer
;; S Normalized small integer
;; D Digit (small integer, 0..999)
-;; L Normalized bignum digit list (without "bigpos" or "bigneg" symbol)
-;; or normalized vector element list (without "vec")
+;; L normalized vector element list (without "vec")
;; P Predicate (truth value)
;; X Any Lisp object
;; Z "nil"
@@ -2617,44 +2549,7 @@ largest Emacs integer.")
(defun math-normalize (a)
(setq math-normalize-error nil)
(cond
- ((not (consp a))
- (if (integerp a)
- (if (or (>= a math-small-integer-size)
- (<= a (- math-small-integer-size)))
- (math-bignum a)
- a)
- a))
- ((eq (car a) 'bigpos)
- (if (eq (nth (1- (length a)) a) 0)
- (let* ((last (setq a
- (copy-sequence a)))
- (digs a))
- (while (setq digs (cdr digs))
- (or (eq (car digs) 0) (setq last digs)))
- (setcdr last nil)))
- (if (cdr (cdr (cdr a)))
- a
- (cond
- ((cdr (cdr a)) (+ (nth 1 a)
- (* (nth 2 a)
- math-bignum-digit-size)))
- ((cdr a) (nth 1 a))
- (t 0))))
- ((eq (car a) 'bigneg)
- (if (eq (nth (1- (length a)) a) 0)
- (let* ((last (setq a (copy-sequence a)))
- (digs a))
- (while (setq digs (cdr digs))
- (or (eq (car digs) 0) (setq last digs)))
- (setcdr last nil)))
- (if (cdr (cdr (cdr a)))
- a
- (cond
- ((cdr (cdr a)) (- (+ (nth 1 a)
- (* (nth 2 a)
- math-bignum-digit-size))))
- ((cdr a) (- (nth 1 a)))
- (t 0))))
+ ((not (consp a)) a)
((eq (car a) 'float)
(math-make-float (math-normalize (nth 1 a))
(nth 2 a)))
@@ -2766,23 +2661,6 @@ largest Emacs integer.")
((consp a) a)
(t (error "Invalid data object encountered"))))
-
-
-;; Coerce integer A to be a bignum. [B S]
-(defun math-bignum (a)
- (cond
- ((>= a 0)
- (cons 'bigpos (math-bignum-big a)))
- (t
- (cons 'bigneg (math-bignum-big (- a))))))
-
-(defun math-bignum-big (a) ; [L s]
- (if (= a 0)
- nil
- (cons (% a math-bignum-digit-size)
- (math-bignum-big (/ a math-bignum-digit-size)))))
-
-
;; Build a normalized floating-point number. [F I S]
(defun math-make-float (mant exp)
(if (eq mant 0)
@@ -2791,20 +2669,9 @@ largest Emacs integer.")
(if (< ldiff 0)
(setq mant (math-scale-rounding mant ldiff)
exp (- exp ldiff))))
- (if (consp mant)
- (let ((digs (cdr mant)))
- (if (= (% (car digs) 10) 0)
- (progn
- (while (= (car digs) 0)
- (setq digs (cdr digs)
- exp (+ exp math-bignum-digit-length)))
- (while (= (% (car digs) 10) 0)
- (setq digs (math-div10-bignum digs)
- exp (1+ exp)))
- (setq mant (math-normalize (cons (car mant) digs))))))
- (while (= (% mant 10) 0)
- (setq mant (/ mant 10)
- exp (1+ exp))))
+ (while (= (% mant 10) 0)
+ (setq mant (/ mant 10)
+ exp (1+ exp)))
(if (and (<= exp -4000000)
(<= (+ exp (math-numdigs mant) -1) -4000000))
(signal 'math-underflow nil)
@@ -2813,13 +2680,6 @@ largest Emacs integer.")
(signal 'math-overflow nil)
(list 'float mant exp)))))
-(defun math-div10-bignum (a) ; [l l]
- (if (cdr a)
- (cons (+ (/ (car a) 10) (* (% (nth 1 a) 10)
- (expt 10 (1- math-bignum-digit-length))))
- (math-div10-bignum (cdr a)))
- (list (/ (car a) 10))))
-
;;; Coerce A to be a float. [F N; V V] [Public]
(defun math-float (a)
(cond ((Math-integerp a) (math-make-float a 0))
@@ -2832,8 +2692,6 @@ largest Emacs integer.")
(defun math-neg (a)
(cond ((not (consp a)) (- a))
- ((eq (car a) 'bigpos) (cons 'bigneg (cdr a)))
- ((eq (car a) 'bigneg) (cons 'bigpos (cdr a)))
((memq (car a) '(frac float))
(list (car a) (Math-integer-neg (nth 1 a)) (nth 2 a)))
((memq (car a) '(cplx vec hms date calcFunc-idn))
@@ -2843,19 +2701,19 @@ largest Emacs integer.")
;;; Compute the number of decimal digits in integer A. [S I]
(defun math-numdigs (a)
- (if (consp a)
- (if (cdr a)
- (let* ((len (1- (length a)))
- (top (nth len a)))
- (+ (* (1- len) math-bignum-digit-length) (math-numdigs top)))
- 0)
- (cond ((>= a 100) (+ (math-numdigs (/ a 1000)) 3))
- ((>= a 10) 2)
- ((>= a 1) 1)
- ((= a 0) 0)
- ((> a -10) 1)
- ((> a -100) 2)
- (t (math-numdigs (- a))))))
+ (cond
+ ((= a 0) 0)
+ ((progn (when (< a 0) (setq a (- a)))
+ (>= a 100))
+ (let* ((bd (logb a))
+ (d (truncate (/ bd (eval-when-compile (log 10 2))))))
+ (let ((b (expt 10 d)))
+ (cond
+ ((> b a) d)
+ ((> (* 10 b) a) (1+ d))
+ (t (+ d 2))))))
+ ((>= a 10) 2)
+ (t 1)))
;;; Multiply (with truncation toward 0) the integer A by 10^N. [I i S]
(defun math-scale-int (a n)
@@ -2866,76 +2724,23 @@ largest Emacs integer.")
(defun math-scale-left (a n) ; [I I S]
(if (= n 0)
a
- (if (consp a)
- (cons (car a) (math-scale-left-bignum (cdr a) n))
- (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 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 math-bignum-digit-length)
- (while (>= (setq a (cons 0 a)
- n (- n math-bignum-digit-length))
- math-bignum-digit-length)))
- (if (> n 0)
- (math-mul-bignum-digit a (expt 10 n) 0)
- a))
+ (* a (expt 10 n))))
(defun math-scale-right (a n) ; [i i S]
(if (= n 0)
a
- (if (consp a)
- (cons (car a) (math-scale-right-bignum (cdr a) n))
- (if (<= a 0)
- (if (= a 0)
- 0
- (- (math-scale-right (- a) n)))
- (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 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 (expt 10 (- math-bignum-digit-length n)) 0))
- a))
+ (if (<= a 0)
+ (if (= a 0)
+ 0
+ (- (math-scale-right (- a) n)))
+ (if (> n 0)
+ (/ a (expt 10 n))
+ a))))
;;; Multiply (with rounding) the integer A by 10^N. [I i S]
(defun math-scale-rounding (a n)
(cond ((>= n 0)
(math-scale-left a n))
- ((consp a)
- (math-normalize
- (cons (car a)
- (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)) (1- math-bignum-digit-size))
- (math-add-bignum (cdr val) '(1))
- (cons (1+ (car (cdr val))) (cdr (cdr val))))
- '(1))
- (cdr val))))))
(t
(if (< a 0)
(- (math-scale-rounding (- a) n))
@@ -2948,36 +2753,13 @@ largest Emacs integer.")
(defun math-add (a b)
(or
(and (not (or (consp a) (consp b)))
- (progn
- (setq a (+ a b))
- (if (or (<= a (- math-small-integer-size)) (>= a math-small-integer-size))
- (math-bignum a)
- a)))
+ (+ a b))
(and (Math-zerop a) (not (eq (car-safe a) 'mod))
(if (and (math-floatp a) (Math-ratp b)) (math-float b) b))
(and (Math-zerop b) (not (eq (car-safe b) 'mod))
(if (and (math-floatp b) (Math-ratp a)) (math-float a) a))
(and (Math-objvecp a) (Math-objvecp b)
(or
- (and (Math-integerp a) (Math-integerp b)
- (progn
- (or (consp a) (setq a (math-bignum a)))
- (or (consp b) (setq b (math-bignum b)))
- (if (eq (car a) 'bigneg)
- (if (eq (car b) 'bigneg)
- (cons 'bigneg (math-add-bignum (cdr a) (cdr b)))
- (math-normalize
- (let ((diff (math-sub-bignum (cdr b) (cdr a))))
- (if (eq diff 'neg)
- (cons 'bigneg (math-sub-bignum (cdr a) (cdr b)))
- (cons 'bigpos diff)))))
- (if (eq (car b) 'bigneg)
- (math-normalize
- (let ((diff (math-sub-bignum (cdr a) (cdr b))))
- (if (eq diff 'neg)
- (cons 'bigneg (math-sub-bignum (cdr b) (cdr a)))
- (cons 'bigpos diff))))
- (cons 'bigpos (math-add-bignum (cdr a) (cdr b)))))))
(and (Math-ratp a) (Math-ratp b)
(require 'calc-ext)
(calc-add-fractions a b))
@@ -2993,79 +2775,6 @@ largest Emacs integer.")
(and (require 'calc-ext)
(math-add-symb-fancy a b))))
-(defun math-add-bignum (a b) ; [L L L; l l l]
- (if a
- (if b
- (let* ((a (copy-sequence a)) (aa a) (carry nil) sum)
- (while (and aa b)
- (if carry
- (if (< (setq sum (+ (car aa) (car b)))
- (1- math-bignum-digit-size))
- (progn
- (setcar aa (1+ sum))
- (setq carry nil))
- (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 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) (1- math-bignum-digit-size))
- (setcar aa 0)
- (setq aa (cdr aa)))
- (if aa
- (progn
- (setcar aa (1+ (car aa)))
- a)
- (nconc a '(1))))
- (if b
- (nconc a b)
- a)))
- a)
- b))
-
-(defun math-sub-bignum (a b) ; [l l l]
- (if b
- (if a
- (let* ((a (copy-sequence a)) (aa a) (borrow nil) diff)
- (while (and aa b)
- (if borrow
- (if (>= (setq diff (- (car aa) (car b))) 1)
- (progn
- (setcar aa (1- diff))
- (setq borrow nil))
- (setcar aa (+ diff (1- math-bignum-digit-size))))
- (if (>= (setq diff (- (car aa) (car b))) 0)
- (setcar aa diff)
- (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 (1- math-bignum-digit-size))
- (setq aa (cdr aa)))
- (if aa
- (progn
- (setcar aa (1- (car aa)))
- a)
- 'neg))
- (while (eq (car b) 0)
- (setq b (cdr b)))
- (if b
- 'neg
- a)))
- (while (eq (car b) 0)
- (setq b (cdr b)))
- (and b
- 'neg))
- a))
-
(defun math-add-float (a b) ; [F F F]
(let ((ediff (- (nth 2 a) (nth 2 b))))
(if (>= ediff 0)
@@ -3088,9 +2797,7 @@ largest Emacs integer.")
(if (or (consp a) (consp b))
(math-add a (math-neg b))
(setq a (- a b))
- (if (or (<= a (- math-small-integer-size)) (>= a math-small-integer-size))
- (math-bignum a)
- a)))
+ a))
(defun math-sub-float (a b) ; [F F F]
(let ((ediff (- (nth 2 a) (nth 2 b))))
@@ -3115,8 +2822,6 @@ largest Emacs integer.")
(defun math-mul (a b)
(or
(and (not (consp a)) (not (consp b))
- (< 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)
@@ -3130,17 +2835,6 @@ largest Emacs integer.")
(math-mul-zero b a)))
(and (Math-objvecp a) (Math-objvecp b)
(or
- (and (Math-integerp a) (Math-integerp b)
- (progn
- (or (consp a) (setq a (math-bignum a)))
- (or (consp b) (setq b (math-bignum b)))
- (math-normalize
- (cons (if (eq (car a) (car b)) 'bigpos 'bigneg)
- (if (cdr (cdr a))
- (if (cdr (cdr b))
- (math-mul-bignum (cdr a) (cdr b))
- (math-mul-bignum-digit (cdr a) (nth 1 b) 0))
- (math-mul-bignum-digit (cdr b) (nth 1 a) 0))))))
(and (Math-ratp a) (Math-ratp b)
(require 'calc-ext)
(calc-mul-fractions a b))
@@ -3169,146 +2863,19 @@ largest Emacs integer.")
'(var uinf var-uinf)
a)))
-;;; Multiply digit lists A and B. [L L L; l l l]
-(defun math-mul-bignum (a b)
- (and a b
- (let* ((sum (if (<= (car b) 1)
- (if (= (car b) 0)
- (list 0)
- (copy-sequence a))
- (math-mul-bignum-digit a (car b) 0)))
- (sump sum) c d aa ss prod)
- (while (setq b (cdr b))
- (setq ss (setq sump (or (cdr sump) (setcdr sump (list 0))))
- d (car b)
- c 0
- aa a)
- (while (progn
- (setcar ss (% (setq prod (+ (+ (car ss) (* (car aa) d))
- c))
- math-bignum-digit-size))
- (setq aa (cdr aa)))
- (setq c (/ prod math-bignum-digit-size)
- ss (or (cdr ss) (setcdr ss (list 0)))))
- (if (>= prod math-bignum-digit-size)
- (if (cdr ss)
- (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]
-(defun math-mul-bignum-digit (a d c)
- (if a
- (if (<= d 1)
- (and (= d 1) a)
- (let* ((a (copy-sequence a)) (aa a) prod)
- (while (progn
- (setcar aa
- (% (setq prod (+ (* (car aa) d) c))
- math-bignum-digit-size))
- (cdr aa))
- (setq aa (cdr aa)
- 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))))
-
-
;;; Compute the integer (quotient . remainder) of A and B, which may be
;;; small or big integers. Type and consistency of truncation is undefined
;;; if A or B is negative. B must be nonzero. [I.I I I] [Public]
(defun math-idivmod (a b)
(if (eq b 0)
(math-reject-arg a "*Division by zero"))
- (if (or (consp a) (consp b))
- (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)))
- (cdr res)))
- (or (consp a) (setq a (math-bignum a)))
- (or (consp b) (setq b (math-bignum b)))
- (let ((res (math-div-bignum (cdr a) (cdr b))))
- (cons
- (math-normalize (cons (if (eq (car a) (car b)) 'bigpos 'bigneg)
- (car res)))
- (math-normalize (cons (car a) (cdr res))))))
- (cons (/ a b) (% a b))))
+ (cons (/ a b) (% a b)))
(defun math-quotient (a b) ; [I I I] [Public]
(if (and (not (consp a)) (not (consp b)))
(if (= b 0)
(math-reject-arg a "*Division by zero")
- (/ a b))
- (if (and (natnump b) (< b math-bignum-digit-size))
- (if (= b 0)
- (math-reject-arg a "*Division by zero")
- (math-normalize (cons (car a)
- (car (math-div-bignum-digit (cdr a) b)))))
- (or (consp a) (setq a (math-bignum a)))
- (or (consp b) (setq b (math-bignum b)))
- (let* ((alen (1- (length a)))
- (blen (1- (length 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)))
- (math-normalize (cons (if (eq (car a) (car b)) 'bigpos 'bigneg)
- (car res)))))))
-
-
-;;; Divide a bignum digit list by another. [l.l l L]
-;;; The following division algorithm is borrowed from Knuth vol. II, sec. 4.3.1
-(defun math-div-bignum (a b)
- (if (cdr b)
- (let* ((alen (length a))
- (blen (length 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)))
- (if (= d 1)
- res
- (cons (car res)
- (car (math-div-bignum-digit (cdr res) d)))))
- (let ((res (math-div-bignum-digit a (car b))))
- (cons (car res) (list (cdr res))))))
-
-;;; Divide a bignum digit list by a digit. [l.D l D]
-(defun math-div-bignum-digit (a b)
- (if a
- (let* ((res (math-div-bignum-digit (cdr a) b))
- (num (+ (* (cdr res) math-bignum-digit-size) (car a))))
- (cons
- (cons (/ num b) (car res))
- (% num b)))
- '(nil . 0)))
-
-(defun math-div-bignum-big (a b alen blen) ; [l.l l L]
- (if (< alen blen)
- (cons nil a)
- (let* ((res (math-div-bignum-big (cdr a) b (1- alen) blen))
- (num (cons (car a) (cdr res)))
- (res2 (math-div-bignum-part num b blen)))
- (cons
- (cons (car res2) (car res))
- (cdr res2)))))
-
-(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) (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]
- (let ((rem (math-sub-bignum a c)))
- (if (eq rem 'neg)
- (math-div-bignum-try a b (math-sub-bignum c b) (1- guess))
- (cons guess rem))))
-
+ (/ a b))))
;;; Compute the quotient of A and B. [O O N] [Public]
(defun math-div (a b)
@@ -3532,11 +3099,11 @@ largest Emacs integer.")
(math-format-binary a)
(math-format-radix a))))
(math-format-radix a))))
- (math-format-number (math-bignum a))))
+ (require 'calc-ext)
+ (declare-function math--format-integer-fancy "calc-ext" (a))
+ (concat (if (< a 0) "-") (math--format-integer-fancy (abs a)))))
((stringp a) a)
((not (consp a)) (prin1-to-string a))
- ((eq (car a) 'bigpos) (math-format-bignum (cdr a)))
- ((eq (car a) 'bigneg) (concat "-" (math-format-bignum (cdr a))))
((and (eq (car a) 'float) (= calc-number-radix 10))
(if (Math-integer-negp (nth 1 a))
(concat "-" (math-format-number (math-neg a)))
@@ -3551,9 +3118,7 @@ largest Emacs integer.")
(> (+ exp (math-numdigs mant)) (- figs))))
(progn
(setq mant (math-scale-rounding mant (+ exp figs))
- str (if (integerp mant)
- (int-to-string mant)
- (math-format-bignum-decimal (cdr mant))))
+ str (int-to-string mant))
(if (<= (length str) figs)
(setq str (concat (make-string (1+ (- figs (length str))) ?0)
str)))
@@ -3571,9 +3136,7 @@ largest Emacs integer.")
(when (< adj 0)
(setq mant (math-scale-rounding mant adj)
exp (- exp adj)))))
- (setq str (if (integerp mant)
- (int-to-string mant)
- (math-format-bignum-decimal (cdr mant))))
+ (setq str (int-to-string mant))
(let* ((len (length str))
(dpos (+ exp len)))
(if (and (eq fmt 'float)
@@ -3617,31 +3180,6 @@ largest Emacs integer.")
(require 'calc-ext)
(math-format-number-fancy a prec))))
-(defun math-format-bignum (a) ; [X L]
- (if (and (= calc-number-radix 10)
- (not calc-leading-zeros)
- (not calc-group-digits))
- (math-format-bignum-decimal a)
- (require 'calc-ext)
- (math-format-bignum-fancy a)))
-
-(defun math-format-bignum-decimal (a) ; [X L]
- (if a
- (let ((s ""))
- (while (cdr (cdr a))
- (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) math-bignum-digit-size) (car a))) s))
- "0"))
-
-
-
;;; Parse a simple number in string form. [N X] [Public]
(defun math-read-number (s &optional decimal)
"Convert the string S into a Calc number."
@@ -3657,9 +3195,7 @@ largest Emacs integer.")
(eq (aref digs 0) ?0)
(null decimal))
(math-read-number (concat "8#" digs))
- (if (<= (length digs) (* 2 math-bignum-digit-length))
- (string-to-number digs)
- (cons 'bigpos (math-read-bignum digs))))))
+ (string-to-number digs))))
;; Clean up the string if necessary
((string-match "\\`\\(.*\\)[ \t\n]+\\([^\001]*\\)\\'" s)
@@ -3714,14 +3250,10 @@ and all digits are kept, regardless of Calc's current precision."
((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))))
+ (string-to-number 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)))))
+ (string-to-number s))
;; Decimal point
((string-match "^\\(-?[0-9]*\\)\\.\\([0-9]*\\)$" s)
(let ((int (math-match-substring s 1))
@@ -3736,12 +3268,6 @@ and all digits are kept, regardless of Calc's current precision."
(substring s (match-beginning n) (match-end n))
""))
-(defun math-read-bignum (s) ; [l X]
- (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))))
-
(defconst math-standard-opers
'( ( "_" calcFunc-subscr 1200 1201 )
( "%" calcFunc-percent 1100 -1 )