summaryrefslogtreecommitdiff
path: root/lisp/calc/calc-comb.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/calc/calc-comb.el')
-rw-r--r--lisp/calc/calc-comb.el75
1 files changed, 42 insertions, 33 deletions
diff --git a/lisp/calc/calc-comb.el b/lisp/calc/calc-comb.el
index cbc81ce8b6c..90a0a20f5d6 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))