home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume24 / gnucalc / part10 < prev    next >
Lisp/Scheme  |  1991-10-29  |  57KB  |  1,789 lines

  1. Newsgroups: comp.sources.misc
  2. From: daveg@synaptics.com (David Gillespie)
  3. Subject:  v24i058:  gnucalc - GNU Emacs Calculator, v2.00, Part10/56
  4. Message-ID: <1991Oct29.230026.20140@sparky.imd.sterling.com>
  5. X-Md4-Signature: 017f2514de54b02b0b894f816e81dee4
  6. Date: Tue, 29 Oct 1991 23:00:26 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: daveg@synaptics.com (David Gillespie)
  10. Posting-number: Volume 24, Issue 58
  11. Archive-name: gnucalc/part10
  12. Environment: Emacs
  13. Supersedes: gmcalc: Volume 13, Issue 27-45
  14.  
  15. ---- Cut Here and unpack ----
  16. #!/bin/sh
  17. # this is Part.10 (part 10 of a multipart archive)
  18. # do not concatenate these parts, unpack them in order with /bin/sh
  19. # file calc-bin.el continued
  20. #
  21. if test ! -r _shar_seq_.tmp; then
  22.     echo 'Please unpack part 1 first!'
  23.     exit 1
  24. fi
  25. (read Scheck
  26.  if test "$Scheck" != 10; then
  27.     echo Please unpack part "$Scheck" next!
  28.     exit 1
  29.  else
  30.     exit 0
  31.  fi
  32. ) < _shar_seq_.tmp || exit 1
  33. if test ! -f _shar_wnt_.tmp; then
  34.     echo 'x - still skipping calc-bin.el'
  35. else
  36. echo 'x - continuing file calc-bin.el'
  37. sed 's/^X//' << 'SHAR_EOF' >> 'calc-bin.el' &&
  38. X  (interactive "NDisplay radix (2-36): ")
  39. X  (calc-wrapper
  40. X   (if (and (>= n 2) (<= n 36))
  41. X       (progn
  42. X     (calc-change-mode 'calc-number-radix n t)
  43. X     ;; also change global value so minibuffer sees it
  44. X     (setq-default calc-number-radix calc-number-radix))
  45. X     (setq n calc-number-radix))
  46. X   (message "Number radix is %d." n))
  47. )
  48. X
  49. (defun calc-decimal-radix ()
  50. X  (interactive)
  51. X  (calc-radix 10)
  52. )
  53. X
  54. (defun calc-binary-radix ()
  55. X  (interactive)
  56. X  (calc-radix 2)
  57. )
  58. X
  59. (defun calc-octal-radix ()
  60. X  (interactive)
  61. X  (calc-radix 8)
  62. )
  63. X
  64. (defun calc-hex-radix ()
  65. X  (interactive)
  66. X  (calc-radix 16)
  67. )
  68. X
  69. (defun calc-leading-zeros (n)
  70. X  (interactive "P")
  71. X  (calc-wrapper
  72. X   (if (calc-change-mode 'calc-leading-zeros n t t)
  73. X       (message "Zero-padding integers to %d digits (assuming radix %d)."
  74. X        (let* ((calc-internal-prec 6))
  75. X          (math-compute-max-digits (math-abs calc-word-size)
  76. X                       calc-number-radix))
  77. X        calc-number-radix)
  78. X     (message "Omitting leading zeros on integers.")))
  79. )
  80. X
  81. X
  82. (defvar math-power-of-2-cache (list 1 2 4 8 16 32 64 128 256 512 1024))
  83. (defvar math-big-power-of-2-cache nil)
  84. (defun math-power-of-2 (n)    ;  [I I] [Public]
  85. X  (if (and (natnump n) (<= n 100))
  86. X      (or (nth n math-power-of-2-cache)
  87. X      (let* ((i (length math-power-of-2-cache))
  88. X         (val (nth (1- i) math-power-of-2-cache)))
  89. X        (while (<= i n)
  90. X          (setq val (math-mul val 2)
  91. X            math-power-of-2-cache (nconc math-power-of-2-cache
  92. X                         (list val))
  93. X            i (1+ i)))
  94. X        val))
  95. X    (let ((found (assq n math-big-power-of-2-cache)))
  96. X      (if found
  97. X      (cdr found)
  98. X    (let ((po2 (math-ipow 2 n)))
  99. X      (setq math-big-power-of-2-cache
  100. X        (cons (cons n po2) math-big-power-of-2-cache))
  101. X      po2))))
  102. )
  103. X
  104. (defun math-integer-log2 (n)    ; [I I] [Public]
  105. X  (let ((i 0)
  106. X    (p math-power-of-2-cache)
  107. X    val)
  108. X    (while (and p (Math-natnum-lessp (setq val (car p)) n))
  109. X      (setq p (cdr p)
  110. X        i (1+ i)))
  111. X    (if p
  112. X    (and (equal val n)
  113. X         i)
  114. X      (while (Math-natnum-lessp
  115. X          (prog1
  116. X          (setq val (math-mul val 2))
  117. X        (setq math-power-of-2-cache (nconc math-power-of-2-cache
  118. X                           (list val))))
  119. X          n)
  120. X    (setq i (1+ i)))
  121. X      (and (equal val n)
  122. X       i)))
  123. )
  124. X
  125. X
  126. X
  127. X
  128. ;;; Bitwise operations.
  129. X
  130. (defun calcFunc-and (a b &optional w)   ; [I I I] [Public]
  131. X  (cond ((Math-messy-integerp w)
  132. X     (calcFunc-and a b (math-trunc w)))
  133. X    ((and w (not (integerp w)))
  134. X     (math-reject-arg w 'fixnump))
  135. X    ((and (integerp a) (integerp b))
  136. X     (math-clip (logand a b) w))
  137. X    ((or (eq (car-safe a) 'mod) (eq (car-safe b) 'mod))
  138. X     (math-binary-modulo-args 'calcFunc-and a b w))
  139. X    ((not (Math-num-integerp a))
  140. X     (math-reject-arg a 'integerp))
  141. X    ((not (Math-num-integerp b))
  142. X     (math-reject-arg b 'integerp))
  143. X    (t (math-clip (cons 'bigpos
  144. X                (math-and-bignum (math-binary-arg a w)
  145. X                         (math-binary-arg b w)))
  146. X              w)))
  147. )
  148. X
  149. (defun math-binary-arg (a w)
  150. X  (if (not (Math-integerp a))
  151. X      (setq a (math-trunc a)))
  152. X  (if (Math-integer-negp a)
  153. X      (math-not-bignum (cdr (math-bignum-test (math-sub -1 a)))
  154. X               (math-abs (if w (math-trunc w) calc-word-size)))
  155. X    (cdr (Math-bignum-test a)))
  156. )
  157. X
  158. (defun math-binary-modulo-args (f a b w)
  159. X  (let (mod)
  160. X    (if (eq (car-safe a) 'mod)
  161. X    (progn
  162. X      (setq mod (nth 2 a)
  163. X        a (nth 1 a))
  164. X      (if (eq (car-safe b) 'mod)
  165. X          (if (equal mod (nth 2 b))
  166. X          (setq b (nth 1 b))
  167. X        (math-reject-arg b "*Inconsistent modulos"))))
  168. X      (setq mod (nth 2 b)
  169. X        b (nth 1 b)))
  170. X    (if (Math-messy-integerp mod)
  171. X    (setq mod (math-trunc mod))
  172. X      (or (Math-integerp mod)
  173. X      (math-reject-arg mod 'integerp)))
  174. X    (let ((bits (math-integer-log2 mod)))
  175. X      (if bits
  176. X      (if w
  177. X          (if (/= w bits)
  178. X          (calc-record-why
  179. X           "*Warning: Modulo inconsistent with word size"))
  180. X        (setq w bits))
  181. X    (calc-record-why "*Warning: Modulo is not a power of 2"))
  182. X      (math-make-mod (if b
  183. X             (funcall f a b w)
  184. X               (funcall f a w))
  185. X             mod)))
  186. )
  187. X
  188. (defun math-and-bignum (a b)   ; [l l l]
  189. X  (and a b
  190. X       (let ((qa (math-div-bignum-digit a 512))
  191. X         (qb (math-div-bignum-digit b 512)))
  192. X     (math-mul-bignum-digit (math-and-bignum (math-norm-bignum (car qa))
  193. X                          (math-norm-bignum (car qb)))
  194. X                 512
  195. X                 (logand (cdr qa) (cdr qb)))))
  196. )
  197. X
  198. (defun calcFunc-or (a b &optional w)   ; [I I I] [Public]
  199. X  (cond ((Math-messy-integerp w)
  200. X     (calcFunc-or a b (math-trunc w)))
  201. X    ((and w (not (integerp w)))
  202. X     (math-reject-arg w 'fixnump))
  203. X    ((and (integerp a) (integerp b))
  204. X     (math-clip (logior a b) w))
  205. X    ((or (eq (car-safe a) 'mod) (eq (car-safe b) 'mod))
  206. X     (math-binary-modulo-args 'calcFunc-or a b w))
  207. X    ((not (Math-num-integerp a))
  208. X     (math-reject-arg a 'integerp))
  209. X    ((not (Math-num-integerp b))
  210. X     (math-reject-arg b 'integerp))
  211. X    (t (math-clip (cons 'bigpos
  212. X                (math-or-bignum (math-binary-arg a w)
  213. X                        (math-binary-arg b w)))
  214. X              w)))
  215. )
  216. X
  217. (defun math-or-bignum (a b)   ; [l l l]
  218. X  (and (or a b)
  219. X       (let ((qa (math-div-bignum-digit a 512))
  220. X         (qb (math-div-bignum-digit b 512)))
  221. X     (math-mul-bignum-digit (math-or-bignum (math-norm-bignum (car qa))
  222. X                         (math-norm-bignum (car qb)))
  223. X                 512
  224. X                 (logior (cdr qa) (cdr qb)))))
  225. )
  226. X
  227. (defun calcFunc-xor (a b &optional w)   ; [I I I] [Public]
  228. X  (cond ((Math-messy-integerp w)
  229. X     (calcFunc-xor a b (math-trunc w)))
  230. X    ((and w (not (integerp w)))
  231. X     (math-reject-arg w 'fixnump))
  232. X    ((and (integerp a) (integerp b))
  233. X     (math-clip (logxor a b) w))
  234. X    ((or (eq (car-safe a) 'mod) (eq (car-safe b) 'mod))
  235. X     (math-binary-modulo-args 'calcFunc-xor a b w))
  236. X    ((not (Math-num-integerp a))
  237. X     (math-reject-arg a 'integerp))
  238. X    ((not (Math-num-integerp b))
  239. X     (math-reject-arg b 'integerp))
  240. X    (t (math-clip (cons 'bigpos
  241. X                (math-xor-bignum (math-binary-arg a w)
  242. X                         (math-binary-arg b w)))
  243. X              w)))
  244. )
  245. X
  246. (defun math-xor-bignum (a b)   ; [l l l]
  247. X  (and (or a b)
  248. X       (let ((qa (math-div-bignum-digit a 512))
  249. X         (qb (math-div-bignum-digit b 512)))
  250. X     (math-mul-bignum-digit (math-xor-bignum (math-norm-bignum (car qa))
  251. X                          (math-norm-bignum (car qb)))
  252. X                 512
  253. X                 (logxor (cdr qa) (cdr qb)))))
  254. )
  255. X
  256. (defun calcFunc-diff (a b &optional w)   ; [I I I] [Public]
  257. X  (cond ((Math-messy-integerp w)
  258. X     (calcFunc-diff a b (math-trunc w)))
  259. X    ((and w (not (integerp w)))
  260. X     (math-reject-arg w 'fixnump))
  261. X    ((and (integerp a) (integerp b))
  262. X     (math-clip (logand a (lognot b)) w))
  263. X    ((or (eq (car-safe a) 'mod) (eq (car-safe b) 'mod))
  264. X     (math-binary-modulo-args 'calcFunc-diff a b w))
  265. X    ((not (Math-num-integerp a))
  266. X     (math-reject-arg a 'integerp))
  267. X    ((not (Math-num-integerp b))
  268. X     (math-reject-arg b 'integerp))
  269. X    (t (math-clip (cons 'bigpos
  270. X                (math-diff-bignum (math-binary-arg a w)
  271. X                          (math-binary-arg b w)))
  272. X              w)))
  273. )
  274. X
  275. (defun math-diff-bignum (a b)   ; [l l l]
  276. X  (and a
  277. X       (let ((qa (math-div-bignum-digit a 512))
  278. X         (qb (math-div-bignum-digit b 512)))
  279. X     (math-mul-bignum-digit (math-diff-bignum (math-norm-bignum (car qa))
  280. X                           (math-norm-bignum (car qb)))
  281. X                 512
  282. X                 (logand (cdr qa) (lognot (cdr qb))))))
  283. )
  284. X
  285. (defun calcFunc-not (a &optional w)   ; [I I] [Public]
  286. X  (cond ((Math-messy-integerp w)
  287. X     (calcFunc-not a (math-trunc w)))
  288. X    ((eq (car-safe a) 'mod)
  289. X     (math-binary-modulo-args 'calcFunc-not a nil w))
  290. X    ((and w (not (integerp w)))
  291. X     (math-reject-arg w 'fixnump))
  292. X    ((not (Math-num-integerp a))
  293. X     (math-reject-arg a 'integerp))
  294. X    ((< (or w (setq w calc-word-size)) 0)
  295. X     (math-clip (calcFunc-not a (- w)) w))
  296. X    (t (math-normalize
  297. X        (cons 'bigpos
  298. X          (math-not-bignum (math-binary-arg a w)
  299. X                   w)))))
  300. )
  301. X
  302. (defun math-not-bignum (a w)   ; [l l]
  303. X  (let ((q (math-div-bignum-digit a 512)))
  304. X    (if (<= w 9)
  305. X    (list (logand (lognot (cdr q))
  306. X              (1- (lsh 1 w))))
  307. X      (math-mul-bignum-digit (math-not-bignum (math-norm-bignum (car q))
  308. X                           (- w 9))
  309. X                  512
  310. X                  (logxor (cdr q) 511))))
  311. )
  312. X
  313. (defun calcFunc-lsh (a &optional n w)   ; [I I] [Public]
  314. X  (setq a (math-trunc a)
  315. X    n (if n (math-trunc n) 1))
  316. X  (if (eq (car-safe a) 'mod)
  317. X      (math-binary-modulo-args 'calcFunc-lsh a n w)
  318. X    (setq w (if w (math-trunc w) calc-word-size))
  319. X    (or (integerp w)
  320. X    (math-reject-arg w 'fixnump))
  321. X    (or (Math-integerp a)
  322. X    (math-reject-arg a 'integerp))
  323. X    (or (Math-integerp n)
  324. X    (math-reject-arg n 'integerp))
  325. X    (if (< w 0)
  326. X    (math-clip (calcFunc-lsh a n (- w)) w)
  327. X      (if (Math-integer-negp a)
  328. X      (setq a (math-clip a w)))
  329. X      (cond ((or (Math-lessp n (- w))
  330. X         (Math-lessp w n))
  331. X         0)
  332. X        ((< n 0)
  333. X         (math-quotient (math-clip a w) (math-power-of-2 (- n))))
  334. X        (t
  335. X         (math-clip (math-mul a (math-power-of-2 n)) w)))))
  336. )
  337. X
  338. (defun calcFunc-rsh (a &optional n w)   ; [I I] [Public]
  339. X  (calcFunc-lsh a (math-neg (or n 1)) w)
  340. )
  341. X
  342. (defun calcFunc-ash (a &optional n w)   ; [I I] [Public]
  343. X  (if (or (null n)
  344. X      (not (Math-negp n)))
  345. X      (calcFunc-lsh a n w)
  346. X    (setq a (math-trunc a)
  347. X      n (if n (math-trunc n) 1))
  348. X    (if (eq (car-safe a) 'mod)
  349. X    (math-binary-modulo-args 'calcFunc-ash a n w)
  350. X      (setq w (if w (math-trunc w) calc-word-size))
  351. X      (or (integerp w)
  352. X      (math-reject-arg w 'fixnump))
  353. X      (or (Math-integerp a)
  354. X      (math-reject-arg a 'integerp))
  355. X      (or (Math-integerp n)
  356. X      (math-reject-arg n 'integerp))
  357. X      (if (< w 0)
  358. X      (math-clip (calcFunc-ash a n (- w)) w)
  359. X    (if (Math-integer-negp a)
  360. X        (setq a (math-clip a w)))
  361. X    (let ((two-to-sizem1 (math-power-of-2 (1- w)))
  362. X          (sh (calcFunc-lsh a n w)))
  363. X      (cond ((Math-natnum-lessp a two-to-sizem1)
  364. X         sh)
  365. X        ((Math-lessp n (- 1 w))
  366. X         (math-add (math-mul two-to-sizem1 2) -1))
  367. X        (t (let ((two-to-n (math-power-of-2 (- n))))
  368. X             (math-add (calcFunc-lsh (math-add two-to-n -1)
  369. X                         (+ w n) w)
  370. X                   sh))))))))
  371. )
  372. X
  373. (defun calcFunc-rash (a &optional n w)   ; [I I] [Public]
  374. X  (calcFunc-ash a (math-neg (or n 1)) w)
  375. )
  376. X
  377. (defun calcFunc-rot (a &optional n w)   ; [I I] [Public]
  378. X  (setq a (math-trunc a)
  379. X    n (if n (math-trunc n) 1))
  380. X  (if (eq (car-safe a) 'mod)
  381. X      (math-binary-modulo-args 'calcFunc-rot a n w)
  382. X    (setq w (if w (math-trunc w) calc-word-size))
  383. X    (or (integerp w)
  384. X    (math-reject-arg w 'fixnump))
  385. X    (or (Math-integerp a)
  386. X    (math-reject-arg a 'integerp))
  387. X    (or (Math-integerp n)
  388. X    (math-reject-arg n 'integerp))
  389. X    (if (< w 0)
  390. X    (math-clip (calcFunc-rot a n (- w)) w)
  391. X      (if (Math-integer-negp a)
  392. X      (setq a (math-clip a w)))
  393. X      (cond ((or (Math-integer-negp n)
  394. X         (not (Math-natnum-lessp n w)))
  395. X         (calcFunc-rot a (math-mod n w) w))
  396. X        (t
  397. X         (math-add (calcFunc-lsh a (- n w) w)
  398. X               (calcFunc-lsh a n w))))))
  399. )
  400. X
  401. (defun math-clip (a &optional w)   ; [I I] [Public]
  402. X  (cond ((Math-messy-integerp w)
  403. X     (math-clip a (math-trunc w)))
  404. X    ((eq (car-safe a) 'mod)
  405. X     (math-binary-modulo-args 'math-clip a nil w))
  406. X    ((and w (not (integerp w)))
  407. X     (math-reject-arg w 'fixnump))
  408. X    ((not (Math-num-integerp a))
  409. X     (math-reject-arg a 'integerp))
  410. X    ((< (or w (setq w calc-word-size)) 0)
  411. X     (setq a (math-clip a (- w)))
  412. X     (if (Math-natnum-lessp a (math-power-of-2 (- -1 w)))
  413. X         a
  414. X       (math-sub a (math-power-of-2 (- w)))))
  415. X    ((Math-negp a)
  416. X     (math-normalize (cons 'bigpos (math-binary-arg a w))))
  417. X    ((and (integerp a) (< a 1000000))
  418. X     (if (>= w 20)
  419. X         a
  420. X       (logand a (1- (lsh 1 w)))))
  421. X    (t
  422. X     (math-normalize
  423. X      (cons 'bigpos
  424. X        (math-clip-bignum (cdr (math-bignum-test (math-trunc a)))
  425. X                  w)))))
  426. )
  427. (fset 'calcFunc-clip (symbol-function 'math-clip))
  428. X
  429. (defun math-clip-bignum (a w)   ; [l l]
  430. X  (let ((q (math-div-bignum-digit a 512)))
  431. X    (if (<= w 9)
  432. X    (list (logand (cdr q)
  433. X              (1- (lsh 1 w))))
  434. X      (math-mul-bignum-digit (math-clip-bignum (math-norm-bignum (car q))
  435. X                        (- w 9))
  436. X                  512
  437. X                  (cdr q))))
  438. )
  439. X
  440. X
  441. X
  442. X
  443. (defvar math-max-digits-cache nil)
  444. (defun math-compute-max-digits (w r)
  445. X  (let* ((pair (+ (* r 100000) w))
  446. X     (res (assq pair math-max-digits-cache)))
  447. X    (if res
  448. X    (cdr res)
  449. X      (let* ((calc-command-flags nil)
  450. X         (digs (math-ceiling (math-div w (math-real-log2 r)))))
  451. X    (setq math-max-digits-cache (cons (cons pair digs)
  452. X                      math-max-digits-cache))
  453. X    digs)))
  454. )
  455. X
  456. (defvar math-log2-cache (list '(2 . 1)
  457. X                  '(4 . 2)
  458. X                  '(8 . 3)
  459. X                  '(10 . (float 332193 -5))
  460. X                  '(16 . 4)
  461. X                  '(32 . 5)))
  462. (defun math-real-log2 (x)   ;;; calc-internal-prec must be 6
  463. X  (let ((res (assq x math-log2-cache)))
  464. X    (if res
  465. X    (cdr res)
  466. X      (let* ((calc-symbolic-mode nil)
  467. X         (calc-display-working-message nil)
  468. X         (log (calcFunc-log x 2)))
  469. X    (setq math-log2-cache (cons (cons x log) math-log2-cache))
  470. X    log)))
  471. )
  472. X
  473. (defconst math-radix-digits ["0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
  474. X                 "A" "B" "C" "D" "E" "F" "G" "H" "I" "J"
  475. X                 "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T"
  476. X                 "U" "V" "W" "X" "Y" "Z"])
  477. X
  478. (defun math-format-radix (a)   ; [X S]
  479. X  (if (< a calc-number-radix)
  480. X      (if (< a 0)
  481. X      (concat "-" (math-format-radix (- a)))
  482. X    (math-format-radix-digit a))
  483. X    (let ((s ""))
  484. X      (while (> a 0)
  485. X    (setq s (concat (math-format-radix-digit (% a calc-number-radix)) s)
  486. X          a (/ a calc-number-radix)))
  487. X      s))
  488. )
  489. X
  490. (defconst math-binary-digits ["000" "001" "010" "011"
  491. X                  "100" "101" "110" "111"])
  492. (defun math-format-binary (a)   ; [X S]
  493. X  (if (< a 8)
  494. X      (if (< a 0)
  495. X      (concat "-" (math-format-binary (- a)))
  496. X    (math-format-radix a))
  497. X    (let ((s ""))
  498. X      (while (> a 7)
  499. X    (setq s (concat (aref math-binary-digits (% a 8)) s)
  500. X          a (/ a 8)))
  501. X      (concat (math-format-radix a) s)))
  502. )
  503. X
  504. (defun math-format-bignum-radix (a)   ; [X L]
  505. X  (cond ((null a) "0")
  506. X    ((and (null (cdr a))
  507. X          (< (car a) calc-number-radix))
  508. X     (math-format-radix-digit (car a)))
  509. X    (t
  510. X     (let ((q (math-div-bignum-digit a calc-number-radix)))
  511. X       (concat (math-format-bignum-radix (math-norm-bignum (car q)))
  512. X           (math-format-radix-digit (cdr q))))))
  513. )
  514. X
  515. (defun math-format-bignum-binary (a)   ; [X L]
  516. X  (cond ((null a) "0")
  517. X    ((null (cdr a))
  518. X     (math-format-binary (car a)))
  519. X    (t
  520. X     (let ((q (math-div-bignum-digit a 512)))
  521. X       (concat (math-format-bignum-binary (math-norm-bignum (car q)))
  522. X           (aref math-binary-digits (/ (cdr q) 64))
  523. X           (aref math-binary-digits (% (/ (cdr q) 8) 8))
  524. X           (aref math-binary-digits (% (cdr q) 8))))))
  525. )
  526. X
  527. (defun math-format-bignum-octal (a)   ; [X L]
  528. X  (cond ((null a) "0")
  529. X    ((null (cdr a))
  530. X     (math-format-radix (car a)))
  531. X    (t
  532. X     (let ((q (math-div-bignum-digit a 512)))
  533. X       (concat (math-format-bignum-octal (math-norm-bignum (car q)))
  534. X           (math-format-radix-digit (/ (cdr q) 64))
  535. X           (math-format-radix-digit (% (/ (cdr q) 8) 8))
  536. X           (math-format-radix-digit (% (cdr q) 8))))))
  537. )
  538. X
  539. (defun math-format-bignum-hex (a)   ; [X L]
  540. X  (cond ((null a) "0")
  541. X    ((null (cdr a))
  542. X     (math-format-radix (car a)))
  543. X    (t
  544. X     (let ((q (math-div-bignum-digit a 256)))
  545. X       (concat (math-format-bignum-hex (math-norm-bignum (car q)))
  546. X           (math-format-radix-digit (/ (cdr q) 16))
  547. X           (math-format-radix-digit (% (cdr q) 16))))))
  548. )
  549. X
  550. ;;; Decompose into integer and fractional parts, without depending
  551. ;;; on calc-internal-prec.
  552. (defun math-float-parts (a need-frac)    ; returns ( int frac fracdigs )
  553. X  (if (>= (nth 2 a) 0)
  554. X      (list (math-scale-rounding (nth 1 a) (nth 2 a)) '(float 0 0) 0)
  555. X    (let* ((d (math-numdigs (nth 1 a)))
  556. X       (n (- (nth 2 a))))
  557. X      (if need-frac
  558. X      (if (>= n d)
  559. X          (list 0 a n)
  560. X        (let ((qr (math-idivmod (nth 1 a) (math-scale-int 1 n))))
  561. X          (list (car qr) (math-make-float (cdr qr) (- n)) n)))
  562. X    (list (math-scale-rounding (nth 1 a) (nth 2 a))
  563. X          '(float 0 0) 0))))
  564. )
  565. X
  566. (defun math-format-radix-float (a prec)
  567. X  (let ((fmt (car calc-float-format))
  568. X    (figs (nth 1 calc-float-format))
  569. X    (point calc-point-char)
  570. X    (str nil))
  571. X    (if (eq fmt 'fix)
  572. X    (let* ((afigs (math-abs figs))
  573. X           (fp (math-float-parts a (> afigs 0)))
  574. X           (calc-internal-prec (+ 3 (max (nth 2 fp)
  575. X                         (math-convert-radix-digits
  576. X                          afigs t))))
  577. X           (int (car fp))
  578. X           (frac (math-round (math-mul (math-normalize (nth 1 fp))
  579. X                       (math-radix-float-power afigs)))))
  580. X      (if (not (and (math-zerop frac) (math-zerop int) (< figs 0)))
  581. X          (let ((math-radix-explicit-format nil))
  582. X        (let ((calc-group-digits nil))
  583. X          (setq str (if (> afigs 0) (math-format-number frac) ""))
  584. X          (if (< (length str) afigs)
  585. X              (setq str (concat (make-string (- afigs (length str)) ?0)
  586. X                    str))
  587. X            (if (> (length str) afigs)
  588. X            (setq str (substring str 1)
  589. X                  int (math-add int 1))))
  590. X          (setq str (concat (math-format-number int) point str)))
  591. X        (if calc-group-digits
  592. X            (setq str (math-group-float str))))
  593. X        (setq figs 0))))
  594. X    (or str
  595. X    (let* ((prec calc-internal-prec)
  596. X           (afigs (if (> figs 0)
  597. X              figs
  598. X            (max 1 (+ figs
  599. X                  (1- (math-convert-radix-digits
  600. X                       (max prec
  601. X                        (math-numdigs (nth 1 a)))))))))
  602. X           (calc-internal-prec (+ 3 (math-convert-radix-digits afigs t)))
  603. X           (explo -1) (vlo (math-radix-float-power explo))
  604. X           (exphi 1) (vhi (math-radix-float-power exphi))
  605. X           expmid vmid eadj)
  606. X      (setq a (math-normalize a))
  607. X      (if (Math-zerop a)
  608. X          (setq explo 0)
  609. X        (if (math-lessp-float '(float 1 0) a)
  610. X        (while (not (math-lessp-float a vhi))
  611. X          (setq explo exphi vlo vhi
  612. X            exphi (math-mul exphi 2)
  613. X            vhi (math-radix-float-power exphi)))
  614. X          (while (math-lessp-float a vlo)
  615. X        (setq exphi explo vhi vlo
  616. X              explo (math-mul explo 2)
  617. X              vlo (math-radix-float-power explo))))
  618. X        (while (not (eq (math-sub exphi explo) 1))
  619. X          (setq expmid (math-div2 (math-add explo exphi))
  620. X            vmid (math-radix-float-power expmid))
  621. X          (if (math-lessp-float a vmid)
  622. X          (setq exphi expmid vhi vmid)
  623. X        (setq explo expmid vlo vmid)))
  624. X        (setq a (math-div-float a vlo)))
  625. X      (let* ((sc (math-round (math-mul a (math-radix-float-power
  626. X                          (1- afigs)))))
  627. X         (math-radix-explicit-format nil))
  628. X        (let ((calc-group-digits nil))
  629. X          (setq str (math-format-number sc))))
  630. X      (if (> (length str) afigs)
  631. X          (setq str (substring str 0 -1)
  632. X            explo (1+ explo)))
  633. X      (if (and (eq fmt 'float)
  634. X           (math-lessp explo (+ (if (= figs 0)
  635. X                        (1- (math-convert-radix-digits
  636. X                         prec))
  637. X                      afigs)
  638. X                    calc-display-sci-high 1))
  639. X           (math-lessp calc-display-sci-low explo))
  640. X          (let ((dpos (1+ explo)))
  641. X        (cond ((<= dpos 0)
  642. X               (setq str (concat "0" point (make-string (- dpos) ?0)
  643. X                     str)))
  644. X              ((> dpos (length str))
  645. X               (setq str (concat str (make-string (- dpos (length str))
  646. X                              ?0) point)))
  647. X              (t
  648. X               (setq str (concat (substring str 0 dpos) point
  649. X                     (substring str dpos)))))
  650. X        (setq explo nil))
  651. X        (setq eadj (if (eq fmt 'eng)
  652. X               (min (math-mod explo 3) (length str))
  653. X             0)
  654. X          str (concat (substring str 0 (1+ eadj)) point
  655. X                  (substring str (1+ eadj)))))
  656. X      (setq pos (length str))
  657. X      (while (eq (aref str (1- pos)) ?0) (setq pos (1- pos)))
  658. X      (and explo (eq (aref str (1- pos)) ?.) (setq pos (1- pos)))
  659. X      (setq str (substring str 0 pos))
  660. X      (if calc-group-digits
  661. X          (setq str (math-group-float str)))
  662. X      (if explo
  663. X          (let ((estr (let ((calc-number-radix 10)
  664. X                (calc-group-digits nil))
  665. X                (setq estr (math-format-number
  666. X                    (math-sub explo eadj))))))
  667. X        (setq str (if (or (memq calc-language '(math maple))
  668. X                  (> calc-number-radix 14))
  669. X                  (format "%s*%d.^%s" str calc-number-radix estr)
  670. X                (format "%se%s" str estr)))))))
  671. X    str)
  672. )
  673. X
  674. (defun math-convert-radix-digits (n &optional to-dec)
  675. X  (let ((key (cons n (cons to-dec calc-number-radix))))
  676. X    (or (cdr (assoc key math-radix-digits-cache))
  677. X    (let* ((calc-internal-prec 6)
  678. X           (log (math-div (math-real-log2 calc-number-radix)
  679. X                  '(float 332193 -5))))
  680. X      (cdr (car (setq math-radix-digits-cache
  681. X              (cons (cons key (math-ceiling (if to-dec
  682. X                                (math-mul n log)
  683. X                              (math-div n log))))
  684. X                math-radix-digits-cache)))))))
  685. )
  686. (setq math-radix-digits-cache nil)
  687. X
  688. (defun math-radix-float-power (n)
  689. X  (if (eq n 0)
  690. X      '(float 1 0)
  691. X    (or (and (eq calc-number-radix (car math-radix-float-cache-tag))
  692. X         (<= calc-internal-prec (cdr math-radix-float-cache-tag)))
  693. X    (setq math-radix-float-cache-tag (cons calc-number-radix
  694. X                           calc-internal-prec)
  695. X          math-radix-float-cache nil))
  696. X    (math-normalize
  697. X     (or (cdr (assoc n math-radix-float-cache))
  698. X     (cdr (car (setq math-radix-float-cache
  699. X             (cons (cons
  700. X                n
  701. X                (let ((calc-internal-prec
  702. X                       (cdr math-radix-float-cache-tag)))
  703. X                  (if (math-negp n)
  704. X                      (math-div-float '(float 1 0)
  705. X                              (math-radix-float-power
  706. X                               (math-neg n)))
  707. X                    (math-mul-float (math-sqr-float
  708. X                             (math-radix-float-power
  709. X                              (math-div2 n)))
  710. X                            (if (math-evenp n)
  711. X                            '(float 1 0)
  712. X                              (math-float
  713. X                               calc-number-radix))))))
  714. X                   math-radix-float-cache)))))))
  715. )
  716. (setq math-radix-float-cache-tag nil)
  717. X
  718. SHAR_EOF
  719. echo 'File calc-bin.el is complete' &&
  720. chmod 0644 calc-bin.el ||
  721. echo 'restore of calc-bin.el failed'
  722. Wc_c="`wc -c < 'calc-bin.el'`"
  723. test 24864 -eq "$Wc_c" ||
  724.     echo 'calc-bin.el: original size 24864, current size' "$Wc_c"
  725. rm -f _shar_wnt_.tmp
  726. fi
  727. # ============= calc-comb.el ==============
  728. if test -f 'calc-comb.el' -a X"$1" != X"-c"; then
  729.     echo 'x - skipping calc-comb.el (File already exists)'
  730.     rm -f _shar_wnt_.tmp
  731. else
  732. > _shar_wnt_.tmp
  733. echo 'x - extracting calc-comb.el (Text)'
  734. sed 's/^X//' << 'SHAR_EOF' > 'calc-comb.el' &&
  735. ;; Calculator for GNU Emacs, part II [calc-comb.el]
  736. ;; Copyright (C) 1990, 1991 Free Software Foundation, Inc.
  737. ;; Written by Dave Gillespie, daveg@csvax.cs.caltech.edu.
  738. X
  739. ;; This file is part of GNU Emacs.
  740. X
  741. ;; GNU Emacs is distributed in the hope that it will be useful,
  742. ;; but WITHOUT ANY WARRANTY.  No author or distributor
  743. ;; accepts responsibility to anyone for the consequences of using it
  744. ;; or for whether it serves any particular purpose or works at all,
  745. ;; unless he says so in writing.  Refer to the GNU Emacs General Public
  746. ;; License for full details.
  747. X
  748. ;; Everyone is granted permission to copy, modify and redistribute
  749. ;; GNU Emacs, but only under the conditions described in the
  750. ;; GNU Emacs General Public License.   A copy of this license is
  751. ;; supposed to have been given to you along with GNU Emacs so you
  752. ;; can know your rights and responsibilities.  It should be in a
  753. ;; file named COPYING.  Among other things, the copyright notice
  754. ;; and this notice must be preserved on all copies.
  755. X
  756. X
  757. X
  758. ;; This file is autoloaded from calc-ext.el.
  759. (require 'calc-ext)
  760. X
  761. (require 'calc-macs)
  762. X
  763. (defun calc-Need-calc-comb () nil)
  764. X
  765. X
  766. ;;; Combinatorics
  767. X
  768. (defun calc-gcd (arg)
  769. X  (interactive "P")
  770. X  (calc-slow-wrapper
  771. X   (calc-binary-op "gcd" 'calcFunc-gcd arg))
  772. )
  773. X
  774. (defun calc-lcm (arg)
  775. X  (interactive "P")
  776. X  (calc-slow-wrapper
  777. X   (calc-binary-op "lcm" 'calcFunc-lcm arg))
  778. )
  779. X
  780. (defun calc-extended-gcd ()
  781. X  (interactive)
  782. X  (calc-slow-wrapper
  783. X   (calc-enter-result 2 "egcd" (cons 'calcFunc-egcd (calc-top-list-n 2))))
  784. )
  785. X
  786. (defun calc-factorial (arg)
  787. X  (interactive "P")
  788. X  (calc-slow-wrapper
  789. X   (calc-unary-op "fact" 'calcFunc-fact arg))
  790. )
  791. X
  792. (defun calc-gamma (arg)
  793. X  (interactive "P")
  794. X  (calc-slow-wrapper
  795. X   (calc-unary-op "gmma" 'calcFunc-gamma arg))
  796. )
  797. X
  798. (defun calc-double-factorial (arg)
  799. X  (interactive "P")
  800. X  (calc-slow-wrapper
  801. X   (calc-unary-op "dfac" 'calcFunc-dfact arg))
  802. )
  803. X
  804. (defun calc-choose (arg)
  805. X  (interactive "P")
  806. X  (calc-slow-wrapper
  807. X   (if (calc-is-hyperbolic)
  808. X       (calc-binary-op "perm" 'calcFunc-perm arg)
  809. X     (calc-binary-op "chos" 'calcFunc-choose arg)))
  810. )
  811. X
  812. (defun calc-perm (arg)
  813. X  (interactive "P")
  814. X  (calc-hyperbolic-func)
  815. X  (calc-choose arg)
  816. )
  817. X
  818. (defvar calc-last-random-limit '(float 1 0))
  819. (defun calc-random (n)
  820. X  (interactive "P")
  821. X  (calc-slow-wrapper
  822. X   (if n
  823. X       (calc-enter-result 0 "rand" (list 'calcFunc-random
  824. X                     (calc-get-random-limit
  825. X                      (prefix-numeric-value n))))
  826. X     (calc-enter-result 1 "rand" (list 'calcFunc-random
  827. X                       (calc-get-random-limit
  828. X                    (calc-top-n 1))))))
  829. )
  830. X
  831. (defun calc-get-random-limit (val)
  832. X  (if (eq val 0)
  833. X      calc-last-random-limit
  834. X    (setq calc-last-random-limit val))
  835. )
  836. X
  837. (defun calc-rrandom ()
  838. X  (interactive)
  839. X  (calc-slow-wrapper
  840. X   (setq calc-last-random-limit '(float 1 0))
  841. X   (calc-enter-result 0 "rand" (list 'calcFunc-random '(float 1 0))))
  842. )
  843. X
  844. (defun calc-random-again (arg)
  845. X  (interactive "p")
  846. X  (calc-slow-wrapper
  847. X   (while (>= (setq arg (1- arg)) 0)
  848. X     (calc-enter-result 0 "rand" (list 'calcFunc-random
  849. X                       calc-last-random-limit))))
  850. )
  851. X
  852. (defun calc-shuffle (n)
  853. X  (interactive "P")
  854. X  (calc-slow-wrapper
  855. X   (if n
  856. X       (calc-enter-result 1 "shuf" (list 'calcFunc-shuffle
  857. X                     (prefix-numeric-value n)
  858. X                     (calc-get-random-limit
  859. X                      (calc-top-n 1))))
  860. X     (calc-enter-result 2 "shuf" (list 'calcFunc-shuffle
  861. X                       (calc-top-n 1)
  862. X                       (calc-get-random-limit
  863. X                    (calc-top-n 2))))))
  864. )
  865. X
  866. (defun calc-report-prime-test (res)
  867. X  (cond ((eq (car res) t)
  868. X     (calc-record-message "prim" "Prime (guaranteed)"))
  869. X    ((eq (car res) nil)
  870. X     (if (cdr res)
  871. X         (if (eq (nth 1 res) 'unknown)
  872. X         (calc-record-message
  873. X          "prim" "Non-prime (factors unknown)")
  874. X           (calc-record-message
  875. X        "prim" "Non-prime (%s is a factor)"
  876. X        (math-format-number (nth 1 res))))
  877. X       (calc-record-message "prim" "Non-prime")))
  878. X    (t
  879. X     (calc-record-message
  880. X      "prim" "Probably prime (%d iters; %s%% chance of error)"
  881. X      (nth 1 res)
  882. X      (let ((calc-float-format '(fix 2)))
  883. X        (math-format-number (nth 2 res))))))
  884. )
  885. X
  886. (defun calc-prime-test (iters)
  887. X  (interactive "p")
  888. X  (calc-slow-wrapper
  889. X   (let* ((n (calc-top-n 1))
  890. X      (res (math-prime-test n iters)))
  891. X     (calc-report-prime-test res)))
  892. )
  893. X
  894. (defun calc-next-prime (iters)
  895. X  (interactive "p")
  896. X  (calc-slow-wrapper
  897. X   (let ((calc-verbose-nextprime t))
  898. X     (if (calc-is-inverse)
  899. X     (calc-enter-result 1 "prvp" (list 'calcFunc-prevprime
  900. X                       (calc-top-n 1) (math-abs iters)))
  901. X       (calc-enter-result 1 "nxtp" (list 'calcFunc-nextprime
  902. X                     (calc-top-n 1) (math-abs iters))))))
  903. )
  904. X
  905. (defun calc-prev-prime (iters)
  906. X  (interactive "p")
  907. X  (calc-invert-func)
  908. X  (calc-next-prime iters)
  909. )
  910. X
  911. (defun calc-prime-factors (iters)
  912. X  (interactive "p")
  913. X  (calc-slow-wrapper
  914. X   (let ((res (calcFunc-prfac (calc-top-n 1))))
  915. X     (if (not math-prime-factors-finished)
  916. X     (calc-record-message "pfac" "Warning:  May not be fully factored"))
  917. X     (calc-enter-result 1 "pfac" res)))
  918. )
  919. X
  920. (defun calc-totient (arg)
  921. X  (interactive "P")
  922. X  (calc-slow-wrapper
  923. X   (calc-unary-op "phi" 'calcFunc-totient arg))
  924. )
  925. X
  926. (defun calc-moebius (arg)
  927. X  (interactive "P")
  928. X  (calc-slow-wrapper
  929. X   (calc-unary-op "mu" 'calcFunc-moebius arg))
  930. )
  931. X
  932. X
  933. X
  934. X
  935. X
  936. (defun calcFunc-gcd (a b)
  937. X  (if (Math-messy-integerp a)
  938. X      (setq a (math-trunc a)))
  939. X  (if (Math-messy-integerp b)
  940. X      (setq b (math-trunc b)))
  941. X  (cond ((and (Math-integerp a) (Math-integerp b))
  942. X     (math-gcd a b))
  943. X    ((Math-looks-negp a)
  944. X     (calcFunc-gcd (math-neg a) b))
  945. X    ((Math-looks-negp b)
  946. X     (calcFunc-gcd a (math-neg b)))
  947. X    ((Math-zerop a) b)
  948. X    ((Math-zerop b) a)
  949. X    ((and (Math-ratp a)
  950. X          (Math-ratp b))
  951. X     (math-make-frac (math-gcd (if (eq (car-safe a) 'frac) (nth 1 a) a)
  952. X                   (if (eq (car-safe b) 'frac) (nth 1 b) b))
  953. X             (calcFunc-lcm
  954. X              (if (eq (car-safe a) 'frac) (nth 2 a) 1)
  955. X              (if (eq (car-safe b) 'frac) (nth 2 b) 1))))
  956. X    ((not (Math-integerp a))
  957. X     (calc-record-why 'integerp a)
  958. X     (list 'calcFunc-gcd a b))
  959. X    (t
  960. X     (calc-record-why 'integerp b)
  961. X     (list 'calcFunc-gcd a b)))
  962. )
  963. X
  964. (defun calcFunc-lcm (a b)
  965. X  (let ((g (calcFunc-gcd a b)))
  966. X    (if (Math-numberp g)
  967. X    (math-div (math-mul a b) g)
  968. X      (list 'calcFunc-lcm a b)))
  969. )
  970. X
  971. (defun calcFunc-egcd (a b)   ; Knuth section 4.5.2
  972. X  (cond
  973. X   ((not (Math-integerp a))
  974. X    (if (Math-messy-integerp a)
  975. X    (calcFunc-egcd (math-trunc a) b)
  976. X      (calc-record-why 'integerp a)
  977. X      (list 'calcFunc-egcd a b)))
  978. X   ((not (Math-integerp b))
  979. X    (if (Math-messy-integerp b)
  980. X    (calcFunc-egcd a (math-trunc b))
  981. X      (calc-record-why 'integerp b)
  982. X      (list 'calcFunc-egcd a b)))
  983. X   (t
  984. X    (let ((u1 1) (u2 0) (u3 a)
  985. X      (v1 0) (v2 1) (v3 b)
  986. X      t1 t2 q)
  987. X      (while (not (eq v3 0))
  988. X    (setq q (math-idivmod u3 v3)
  989. X          t1 (math-sub u1 (math-mul v1 (car q)))
  990. X          t2 (math-sub u2 (math-mul v2 (car q)))
  991. X          u1 v1  u2 v2  u3 v3
  992. X          v1 t1  v2 t2  v3 (cdr q)))
  993. X      (list 'vec u3 u1 u2))))
  994. )
  995. X
  996. X
  997. ;;; Factorial and related functions.
  998. X
  999. (defun calcFunc-fact (n)   ; [I I] [F F] [Public]
  1000. X  (let (temp)
  1001. X    (cond ((Math-integer-negp n)
  1002. X       (if calc-infinite-mode
  1003. X           '(var uinf var-uinf)
  1004. X         (math-reject-arg n 'range)))
  1005. X      ((integerp n)
  1006. X       (if (<= n 20)
  1007. X           (aref '[1 1 2 6 24 120 720 5040 40320 362880
  1008. X             (bigpos 800 628 3) (bigpos 800 916 39)
  1009. X             (bigpos 600 1 479) (bigpos 800 20 227 6)
  1010. X             (bigpos 200 291 178 87) (bigpos 0 368 674 307 1)
  1011. X             (bigpos 0 888 789 922 20) (bigpos 0 96 428 687 355)
  1012. X             (bigpos 0 728 705 373 402 6)
  1013. X             (bigpos 0 832 408 100 645 121)
  1014. X             (bigpos 0 640 176 8 902 432 2)] n)
  1015. X         (math-factorial-iter (1- n) 2 1)))
  1016. X      ((and (math-messy-integerp n)
  1017. X        (Math-lessp n 100))
  1018. X       (math-inexact-result)
  1019. X       (setq temp (math-trunc n))
  1020. X       (if (>= temp 0)
  1021. X           (if (<= temp 20)
  1022. X           (math-float (calcFunc-fact temp))
  1023. X         (math-with-extra-prec 1
  1024. X           (math-factorial-iter (1- temp) 2 '(float 1 0))))
  1025. X         (math-reject-arg n 'range)))
  1026. X      ((math-numberp n)
  1027. X       (let* ((q (math-quarter-integer n))
  1028. X          (tn (and q (Math-lessp n 1000) (Math-lessp -1000 n)
  1029. X               (1+ (math-floor n)))))
  1030. X         (cond ((and tn (= q 2)
  1031. X             (or calc-symbolic-mode (< (math-abs tn) 20)))
  1032. X            (let ((q (if (< tn 0)
  1033. X                 (math-div
  1034. X                  (math-pow -2 (- tn))
  1035. X                  (math-double-factorial-iter (* -2 tn) 3 1 2))
  1036. X                   (math-div 
  1037. X                (math-double-factorial-iter (* 2 tn) 3 1 2)
  1038. X                (math-pow 2 tn)))))
  1039. X              (math-mul q (if calc-symbolic-mode
  1040. X                      (list 'calcFunc-sqrt '(var pi var-pi))
  1041. X                    (math-sqrt-pi)))))
  1042. X           ((and tn (>= tn 0) (< tn 20)
  1043. X             (memq q '(1 3)))
  1044. X            (math-inexact-result)
  1045. X            (math-div
  1046. X             (math-mul (math-double-factorial-iter (* 4 tn) q 1 4)
  1047. X                   (if (= q 1) (math-gamma-1q) (math-gamma-3q)))
  1048. X             (math-pow 4 tn)))
  1049. X           (t
  1050. X            (math-inexact-result)
  1051. X            (math-with-extra-prec 3
  1052. X              (math-gammap1-raw (math-float n)))))))
  1053. X      ((equal n '(var inf var-inf)) n)
  1054. X      (t (calc-record-why 'numberp n)
  1055. X         (list 'calcFunc-fact n))))
  1056. )
  1057. X
  1058. (math-defcache math-gamma-1q nil
  1059. X  (math-with-extra-prec 3
  1060. X    (math-gammap1-raw '(float -75 -2))))
  1061. X
  1062. (math-defcache math-gamma-3q nil
  1063. X  (math-with-extra-prec 3
  1064. X    (math-gammap1-raw '(float -25 -2))))
  1065. X
  1066. (defun math-factorial-iter (count n f)
  1067. X  (if (= (% n 5) 1)
  1068. X      (math-working (format "factorial(%d)" (1- n)) f))
  1069. X  (if (> count 0)
  1070. X      (math-factorial-iter (1- count) (1+ n) (math-mul n f))
  1071. X    f)
  1072. )
  1073. X
  1074. (defun calcFunc-dfact (n)   ; [I I] [F F] [Public]
  1075. X  (cond ((Math-integer-negp n)
  1076. X     (if (math-oddp n)
  1077. X         (if (eq n -1)
  1078. X         1
  1079. X           (math-div (if (eq (math-mod n 4) 3) 1 -1)
  1080. X             (calcFunc-dfact (math-sub -2 n))))
  1081. X       (list 'calcFunc-dfact n)))
  1082. X    ((Math-zerop n) 1)
  1083. X    ((integerp n) (math-double-factorial-iter n (+ 2 (% n 2)) 1 2))
  1084. X    ((math-messy-integerp n)
  1085. X     (let ((temp (math-trunc n)))
  1086. X       (math-inexact-result)
  1087. X       (if (natnump temp)
  1088. X           (if (Math-lessp temp 200)
  1089. X           (math-with-extra-prec 1
  1090. X             (math-double-factorial-iter temp (+ 2 (% temp 2))
  1091. X                         '(float 1 0) 2))
  1092. X         (let* ((half (math-div2 temp))
  1093. X            (even (math-mul (math-pow 2 half)
  1094. X                    (calcFunc-fact (math-float half)))))
  1095. X           (if (math-evenp temp)
  1096. X               even
  1097. X             (math-div (calcFunc-fact n) even))))
  1098. X         (list 'calcFunc-dfact max))))
  1099. X    ((equal n '(var inf var-inf)) n)
  1100. X    (t (calc-record-why 'natnump n)
  1101. X       (list 'calcFunc-dfact n)))
  1102. )
  1103. X
  1104. (defun math-double-factorial-iter (max n f step)
  1105. X  (if (< (% n 12) step)
  1106. X      (math-working (format "dfact(%d)" (- n step)) f))
  1107. X  (if (<= n max)
  1108. X      (math-double-factorial-iter max (+ n step) (math-mul n f) step)
  1109. X    f)
  1110. )
  1111. X
  1112. (defun calcFunc-perm (n m)   ; [I I I] [F F F] [Public]
  1113. X  (cond ((and (integerp n) (integerp m) (<= m n) (>= m 0))
  1114. X     (math-factorial-iter m (1+ (- n m)) 1))
  1115. X    ((or (not (math-num-integerp n))
  1116. X         (and (math-messy-integerp n) (Math-lessp 100 n))
  1117. X         (not (math-num-integerp m))
  1118. X         (and (math-messy-integerp m) (Math-lessp 100 m)))
  1119. X     (or (math-realp n) (equal n '(var inf var-inf))
  1120. X         (math-reject-arg n 'realp))
  1121. X     (or (math-realp m) (equal m '(var inf var-inf))
  1122. X         (math-reject-arg m 'realp))
  1123. X     (and (math-num-integerp n) (math-negp n) (math-reject-arg n 'range))
  1124. X     (and (math-num-integerp m) (math-negp m) (math-reject-arg m 'range))
  1125. X     (math-div (calcFunc-fact n) (calcFunc-fact (math-sub n m))))
  1126. X    (t
  1127. X     (let ((tn (math-trunc n))
  1128. X           (tm (math-trunc m)))
  1129. X       (math-inexact-result)
  1130. X       (or (integerp tn) (math-reject-arg tn 'fixnump))
  1131. X       (or (integerp tm) (math-reject-arg tm 'fixnump))
  1132. X       (or (and (<= tm tn) (>= tm 0)) (math-reject-arg tm 'range))
  1133. X       (math-with-extra-prec 1
  1134. X         (math-factorial-iter tm (1+ (- tn tm)) '(float 1 0))))))
  1135. )
  1136. X
  1137. (defun calcFunc-choose (n m)   ; [I I I] [F F F] [Public]
  1138. X  (cond ((and (integerp n) (integerp m) (<= m n) (>= m 0))
  1139. X     (if (> m (/ n 2))
  1140. X         (math-choose-iter (- n m) n 1 1)
  1141. X       (math-choose-iter m n 1 1)))
  1142. X    ((not (math-realp n))
  1143. X     (math-reject-arg n 'realp))
  1144. X    ((not (math-realp m))
  1145. X     (math-reject-arg m 'realp))
  1146. X    ((not (math-num-integerp m))
  1147. X     (if (and (math-num-integerp n) (math-negp n))
  1148. X         (list 'calcFunc-choose n m)
  1149. X       (math-div (calcFunc-fact (math-float n))
  1150. X             (math-mul (calcFunc-fact m)
  1151. X                   (calcFunc-fact (math-sub n m))))))
  1152. X    ((math-negp m) 0)
  1153. X    ((math-negp n)
  1154. X     (let ((val (calcFunc-choose (math-add (math-add n m) -1) m)))
  1155. X       (if (math-evenp (math-trunc m))
  1156. X           val
  1157. X         (math-neg val))))
  1158. X    ((and (math-num-integerp n)
  1159. X          (Math-lessp n m))
  1160. X     0)
  1161. X    (t
  1162. X     (math-inexact-result)
  1163. X     (let ((tm (math-trunc m)))
  1164. X       (or (integerp tm) (math-reject-arg tm 'fixnump))
  1165. X       (if (> tm 100)
  1166. X           (math-div (calcFunc-fact (math-float n))
  1167. X             (math-mul (calcFunc-fact (math-float m))
  1168. X                   (calcFunc-fact (math-float
  1169. X                           (math-sub n m)))))
  1170. X         (math-with-extra-prec 1
  1171. X           (math-choose-float-iter tm n 1 1))))))
  1172. )
  1173. X
  1174. (defun math-choose-iter (m n i c)
  1175. X  (if (and (= (% i 5) 1) (> i 5))
  1176. X      (math-working (format "choose(%d)" (1- i)) c))
  1177. X  (if (<= i m)
  1178. X      (math-choose-iter m (1- n) (1+ i)
  1179. X            (math-quotient (math-mul c n) i))
  1180. X    c)
  1181. )
  1182. X
  1183. (defun math-choose-float-iter (count n i c)
  1184. X  (if (= (% i 5) 1)
  1185. X      (math-working (format "choose(%d)" (1- i)) c))
  1186. X  (if (> count 0)
  1187. X      (math-choose-float-iter (1- count) (math-sub n 1) (1+ i)
  1188. X                  (math-div (math-mul c n) i))
  1189. X    c)
  1190. )
  1191. X
  1192. X
  1193. ;;; Stirling numbers.
  1194. X
  1195. (defun calcFunc-stir1 (n m)
  1196. X  (math-stirling-number n m 1)
  1197. )
  1198. X
  1199. (defun calcFunc-stir2 (n m)
  1200. X  (math-stirling-number n m 0)
  1201. )
  1202. X
  1203. (defun math-stirling-number (n m k)
  1204. X  (or (math-num-natnump n) (math-reject-arg n 'natnump))
  1205. X  (or (math-num-natnump m) (math-reject-arg m 'natnump))
  1206. X  (if (consp n) (setq n (math-trunc n)))
  1207. X  (or (integerp n) (math-reject-arg n 'fixnump))
  1208. X  (if (consp m) (setq m (math-trunc m)))
  1209. X  (or (integerp m) (math-reject-arg m 'fixnump))
  1210. X  (if (< n m)
  1211. X      0
  1212. X    (let ((cache (aref math-stirling-cache k)))
  1213. X      (while (<= (length cache) n)
  1214. X    (let ((i (1- (length cache)))
  1215. X          row)
  1216. X      (setq cache (vconcat cache (make-vector (length cache) nil)))
  1217. X      (aset math-stirling-cache k cache)
  1218. X      (while (< (setq i (1+ i)) (length cache))
  1219. X        (aset cache i (setq row (make-vector (1+ i) nil)))
  1220. X        (aset row 0 0)
  1221. X        (aset row i 1))))
  1222. X      (if (= k 1)
  1223. X      (math-stirling-1 n m)
  1224. X    (math-stirling-2 n m))))
  1225. )
  1226. (setq math-stirling-cache (vector [[1]] [[1]]))
  1227. X
  1228. (defun math-stirling-1 (n m)
  1229. X  (or (aref (aref cache n) m)
  1230. X      (aset (aref cache n) m
  1231. X        (math-add (math-stirling-1 (1- n) (1- m))
  1232. X              (math-mul (- 1 n) (math-stirling-1 (1- n) m)))))
  1233. )
  1234. X
  1235. (defun math-stirling-2 (n m)
  1236. X  (or (aref (aref cache n) m)
  1237. X      (aset (aref cache n) m
  1238. X        (math-add (math-stirling-2 (1- n) (1- m))
  1239. X              (math-mul m (math-stirling-2 (1- n) m)))))
  1240. )
  1241. X
  1242. X
  1243. ;;; Produce a random 10-bit integer, with (random) if no seed provided,
  1244. ;;; or else with Numerical Recipes algorithm ran3 / Knuth 3.2.2-A.
  1245. (defun math-init-random-base ()
  1246. X  (if (and (boundp 'var-RandSeed) var-RandSeed)
  1247. X      (if (eq (car-safe var-RandSeed) 'vec)
  1248. X      nil
  1249. X    (if (Math-integerp var-RandSeed)
  1250. X        (let* ((seed (math-sub 161803 var-RandSeed))
  1251. X           (mj (1+ (math-mod seed '(bigpos 0 0 1))))
  1252. X           (mk (1+ (math-mod (math-quotient seed '(bigpos 0 0 1))
  1253. X                     '(bigpos 0 0 1))))
  1254. X           (i 0))
  1255. X          (setq math-random-table (cons 'vec (make-list 55 mj)))
  1256. X          (while (<= (setq i (1+ i)) 54)
  1257. X        (let* ((ii (% (* i 21) 55))
  1258. X               (p (nthcdr ii math-random-table)))
  1259. X          (setcar p mk)
  1260. X          (setq mk (- mj mk)
  1261. X            mj (car p)))))
  1262. X      (math-reject-arg var-RandSeed "*RandSeed must be an integer"))
  1263. X    (setq var-RandSeed (list 'vec var-RandSeed)
  1264. X          math-random-ptr1 math-random-table
  1265. X          math-random-cache nil
  1266. X          math-random-ptr2 (nthcdr 31 math-random-table))
  1267. X    (let ((i 200))
  1268. X      (while (> (setq i (1- i)) 0)
  1269. X        (math-random-base))))
  1270. X    (random t)
  1271. X    (setq var-RandSeed nil
  1272. X      math-random-cache nil
  1273. X      i 0
  1274. X      math-random-shift -4)  ; assume RAND_MAX >= 16383
  1275. X    ;; This exercises the random number generator and also helps
  1276. X    ;; deduce a better value for RAND_MAX.
  1277. X    (while (< (setq i (1+ i)) 30)
  1278. X      (if (> (lsh (math-abs (random)) math-random-shift) 4095)
  1279. X      (setq math-random-shift (1- math-random-shift)))))
  1280. X  (setq math-last-RandSeed var-RandSeed
  1281. X    math-gaussian-cache nil)
  1282. )
  1283. X
  1284. (defun math-random-base ()
  1285. X  (if var-RandSeed
  1286. X      (progn
  1287. X    (setq math-random-ptr1 (or (cdr math-random-ptr1)
  1288. X                   (cdr math-random-table))
  1289. X          math-random-ptr2 (or (cdr math-random-ptr2)
  1290. X                   (cdr math-random-table)))
  1291. X    (logand (lsh (setcar math-random-ptr1
  1292. X                 (logand (- (car math-random-ptr1)
  1293. X                    (car math-random-ptr2)) 524287))
  1294. X             -6) 1023))
  1295. X    (logand (lsh (random) math-random-shift) 1023))
  1296. )
  1297. (setq math-random-table nil)
  1298. (setq math-last-RandSeed nil)
  1299. (setq math-random-ptr1 nil)
  1300. (setq math-random-ptr2 nil)
  1301. (setq math-random-shift nil)
  1302. X
  1303. X
  1304. ;;; Produce a random digit in the range 0..999.
  1305. ;;; Avoid various pitfalls that may lurk in the built-in (random) function!
  1306. ;;; Shuffling algorithm from Numerical Recipes, section 7.1.
  1307. (defun math-random-digit ()
  1308. X  (let (i)
  1309. X    (or (and (boundp 'var-RandSeed) (eq var-RandSeed math-last-RandSeed))
  1310. X    (math-init-random-base))
  1311. X    (or math-random-cache
  1312. X    (progn
  1313. X      (setq math-random-last (math-random-base)
  1314. X        math-random-cache (make-vector 13 nil)
  1315. X        i -1)
  1316. X      (while (< (setq i (1+ i)) 13)
  1317. X        (aset math-random-cache i (math-random-base)))))
  1318. X    (while (progn
  1319. X         (setq i (/ math-random-last 79)   ; 0 <= i < 13
  1320. X           math-random-last (aref math-random-cache i))
  1321. X         (aset math-random-cache i (math-random-base))
  1322. X         (>= math-random-last 1000)))
  1323. X    math-random-last)
  1324. )
  1325. (setq math-random-cache nil)
  1326. X
  1327. ;;; Produce an N-digit random integer.
  1328. (defun math-random-digits (n)
  1329. X  (cond ((<= n 6)
  1330. X     (math-scale-right (+ (* (math-random-digit) 1000) (math-random-digit))
  1331. X               (- 6 n)))
  1332. X    (t (let* ((slop (% (- 900003 n) 3))
  1333. X          (i (/ (+ n slop) 3))
  1334. X          (digs nil))
  1335. X         (while (> i 0)
  1336. X           (setq digs (cons (math-random-digit) digs)
  1337. X             i (1- i)))
  1338. X         (math-normalize (math-scale-right (cons 'bigpos digs)
  1339. X                           slop)))))
  1340. )
  1341. X
  1342. ;;; Produce a uniformly-distributed random float 0 <= N < 1.
  1343. (defun math-random-float ()
  1344. X  (math-make-float (math-random-digits calc-internal-prec)
  1345. X           (- calc-internal-prec))
  1346. )
  1347. X
  1348. ;;; Produce a Gaussian-distributed random float with mean=0, sigma=1.
  1349. (defun math-gaussian-float ()
  1350. X  (math-with-extra-prec 2
  1351. X    (if (and math-gaussian-cache
  1352. X         (= (car math-gaussian-cache) calc-internal-prec))
  1353. X    (prog1
  1354. X        (cdr math-gaussian-cache)
  1355. X      (setq math-gaussian-cache nil))
  1356. X      (let* ((v1 (math-add (math-mul (math-random-float) 2) -1))
  1357. X         (v2 (math-add (math-mul (math-random-float) 2) -1))
  1358. X         (r (math-add (math-sqr v1) (math-sqr v2))))
  1359. X    (while (or (not (Math-lessp r 1)) (math-zerop r))
  1360. X      (setq v1 (math-add (math-mul (math-random-float) 2) -1)
  1361. X        v2 (math-add (math-mul (math-random-float) 2) -1)
  1362. X        r (math-add (math-sqr v1) (math-sqr v2))))
  1363. X    (let ((fac (math-sqrt (math-mul (math-div (calcFunc-ln r) r) -2))))
  1364. X      (setq math-gaussian-cache (cons calc-internal-prec
  1365. X                      (math-mul v1 fac)))
  1366. X      (math-mul v2 fac)))))
  1367. )
  1368. (setq math-gaussian-cache nil)
  1369. X
  1370. ;;; Produce a random integer or real 0 <= N < MAX.
  1371. (defun calcFunc-random (max)
  1372. X  (cond ((Math-zerop max)
  1373. X     (math-gaussian-float))
  1374. X    ((Math-integerp max)
  1375. X     (let* ((digs (math-numdigs max))
  1376. X        (r (math-random-digits (+ digs 3))))
  1377. X       (math-mod r max)))
  1378. X    ((Math-realp max)
  1379. X     (math-mul (math-random-float) max))
  1380. X    ((and (eq (car max) 'intv) (math-constp max)
  1381. X          (Math-lessp (nth 2 max) (nth 3 max)))
  1382. X     (if (math-floatp max)
  1383. X         (let ((val (math-add (math-mul (math-random-float)
  1384. X                        (math-sub (nth 3 max) (nth 2 max)))
  1385. X                  (nth 2 max))))
  1386. X           (if (or (and (memq (nth 1 max) '(0 1))      ; almost not worth
  1387. X                (Math-equal val (nth 2 max)))  ;   checking!
  1388. X               (and (memq (nth 1 max) '(0 2))
  1389. X                (Math-equal val (nth 3 max))))
  1390. X           (calcFunc-random max)
  1391. X         val))
  1392. X       (let ((lo (if (memq (nth 1 max) '(0 1))
  1393. X             (math-add (nth 2 max) 1) (nth 2 max)))
  1394. X         (hi (if (memq (nth 1 max) '(1 3))
  1395. X             (math-add (nth 3 max) 1) (nth 3 max))))
  1396. X         (if (Math-lessp lo hi)
  1397. X         (math-add (calcFunc-random (math-sub hi lo)) lo)
  1398. X           (math-reject-arg max "*Empty interval")))))
  1399. X    ((eq (car max) 'vec)
  1400. X     (if (cdr max)
  1401. X         (nth (1+ (calcFunc-random (1- (length max)))) max)
  1402. X       (math-reject-arg max "*Empty list")))
  1403. X    ((and (eq (car max) 'sdev) (math-constp max) (Math-realp (nth 1 max)))
  1404. X     (math-add (math-mul (math-gaussian-float) (nth 2 max)) (nth 1 max)))
  1405. X    (t (math-reject-arg max 'realp)))
  1406. )
  1407. X
  1408. ;;; Choose N objects at random from the set MAX without duplicates.
  1409. (defun calcFunc-shuffle (n &optional max)
  1410. X  (or max (setq max n n -1))
  1411. X  (or (and (Math-num-integerp n)
  1412. X       (or (natnump (setq n (math-trunc n))) (eq n -1)))
  1413. X      (math-reject-arg n 'integerp))
  1414. X  (cond ((or (math-zerop max)
  1415. X         (math-floatp max)
  1416. X         (eq (car-safe max) 'sdev))
  1417. X     (if (< n 0)
  1418. X         (math-reject-arg n 'natnump)
  1419. X       (math-simple-shuffle n max)))
  1420. X    ((and (<= n 1) (>= n 0))
  1421. X     (math-simple-shuffle n max))
  1422. X    ((and (eq (car-safe max) 'intv) (math-constp max))
  1423. X     (let ((num (math-add (math-sub (nth 3 max) (nth 2 max))
  1424. X                  (cdr (assq (nth 1 max)
  1425. X                     '((0 . -1) (1 . 0)
  1426. X                       (2 . 0) (3 . 1))))))
  1427. X           (min (math-add (nth 2 max) (if (memq (nth 1 max) '(0 1))
  1428. X                          1 0))))
  1429. X       (if (< n 0) (setq n num))
  1430. X       (or (math-posp num) (math-reject-arg max 'range))
  1431. X       (and (Math-lessp num n) (math-reject-arg n 'range))
  1432. X       (if (Math-lessp n (math-quotient num 3))
  1433. X           (math-simple-shuffle n max)
  1434. X         (if (> (* n 4) (* num 3))
  1435. X         (math-add (math-sub min 1)
  1436. X               (math-shuffle-list n num (calcFunc-index num)))
  1437. X           (let ((tot 0)
  1438. X             (m 0)
  1439. X             (vec nil))
  1440. X         (while (< m n)
  1441. X           (if (< (calcFunc-random (- num tot)) (- n m))
  1442. X               (setq vec (cons (math-add min tot) vec)
  1443. X                 m (1+ m)))
  1444. X           (setq tot (1+ tot)))
  1445. X         (math-shuffle-list n n (cons 'vec vec)))))))
  1446. X    ((eq (car-safe max) 'vec)
  1447. X     (let ((size (1- (length max))))
  1448. X       (if (< n 0) (setq n size))
  1449. X       (if (and (> n (/ size 2)) (<= n size))
  1450. X           (math-shuffle-list n size (copy-sequence max))
  1451. X         (let* ((vals (calcFunc-shuffle
  1452. X               n (list 'intv 3 1 (1- (length max)))))
  1453. X            (p vals))
  1454. X           (while (setq p (cdr p))
  1455. X         (setcar p (nth (car p) max)))
  1456. X           vals))))
  1457. X    ((math-integerp max)
  1458. X     (if (math-posp max)
  1459. X         (calcFunc-shuffle n (list 'intv 2 0 max))
  1460. X       (calcFunc-shuffle n (list 'intv 1 max 0))))
  1461. X    (t (math-reject-arg max 'realp)))
  1462. )
  1463. X
  1464. (defun math-simple-shuffle (n max)
  1465. X  (let ((vec nil)
  1466. X    val)
  1467. X    (while (>= (setq n (1- n)) 0)
  1468. X      (while (math-member (setq val (calcFunc-random max)) vec))
  1469. X      (setq vec (cons val vec)))
  1470. X    (cons 'vec vec))
  1471. )
  1472. X
  1473. (defun math-shuffle-list (n size vec)
  1474. X  (let ((j size)
  1475. X    k temp
  1476. X    (p vec))
  1477. X    (while (cdr (setq p (cdr p)))
  1478. X      (setq k (calcFunc-random j)
  1479. X        j (1- j)
  1480. X        temp (nth k p))
  1481. X      (setcar (nthcdr k p) (car p))
  1482. X      (setcar p temp))
  1483. X    (cons 'vec (nthcdr (- size n -1) vec)))
  1484. )
  1485. X
  1486. (defun math-member (x list)
  1487. X  (while (and list (not (equal x (car list))))
  1488. X    (setq list (cdr list)))
  1489. X  list
  1490. )
  1491. X
  1492. X
  1493. ;;; Check if the integer N is prime.  [X I]
  1494. ;;; Return (nil) if non-prime,
  1495. ;;;        (nil N) if non-prime with known factor N,
  1496. ;;;        (nil unknown) if non-prime with no known factors,
  1497. ;;;        (t) if prime,
  1498. ;;;        (maybe N P) if probably prime (after N iters with probability P%)
  1499. (defun math-prime-test (n iters)
  1500. X  (if (and (Math-vectorp n) (cdr n))
  1501. X      (setq n (nth (1- (length n)) n)))
  1502. X  (if (Math-messy-integerp n)
  1503. X      (setq n (math-trunc n)))
  1504. X  (let ((res))
  1505. X    (while (> iters 0)
  1506. X      (setq res
  1507. X        (cond ((and (integerp n) (<= n 5003))
  1508. X           (list (= (math-next-small-prime n) n)))
  1509. X          ((not (Math-integerp n))
  1510. X           (error "Argument must be an integer"))
  1511. X          ((Math-integer-negp n)
  1512. X           '(nil))
  1513. X          ((Math-natnum-lessp n '(bigpos 0 0 8))
  1514. X           (setq n (math-fixnum n))
  1515. X           (let ((i -1) v)
  1516. X             (while (and (> (% n (setq v (aref math-primes-table
  1517. X                               (setq i (1+ i)))))
  1518. X                    0)
  1519. X                 (< (* v v) n)))
  1520. X             (if (= (% n v) 0)
  1521. X             (list nil v)
  1522. X               '(t))))
  1523. X          ((not (equal n (car math-prime-test-cache)))
  1524. X           (cond ((= (% (nth 1 n) 2) 0) '(nil 2))
  1525. X             ((= (% (nth 1 n) 5) 0) '(nil 5))
  1526. X             (t (let ((dig (cdr n)) (sum 0))
  1527. X                  (while dig
  1528. X                (if (cdr dig)
  1529. X                    (setq sum (% (+ (+ sum (car dig))
  1530. X                            (* (nth 1 dig) 1000))
  1531. X                         111111)
  1532. X                      dig (cdr (cdr dig)))
  1533. X                  (setq sum (% (+ sum (car dig)) 111111)
  1534. X                    dig nil)))
  1535. X                  (cond ((= (% sum 3) 0) '(nil 3))
  1536. X                    ((= (% sum 7) 0) '(nil 7))
  1537. X                    ((= (% sum 11) 0) '(nil 11))
  1538. X                    ((= (% sum 13) 0) '(nil 13))
  1539. X                    ((= (% sum 37) 0) '(nil 37))
  1540. X                    (t
  1541. X                     (setq math-prime-test-cache-k 1
  1542. X                       math-prime-test-cache-q
  1543. X                       (math-div2 n)
  1544. X                       math-prime-test-cache-nm1
  1545. X                       (math-add n -1))
  1546. X                     (while (math-evenp
  1547. X                         math-prime-test-cache-q)
  1548. X                       (setq math-prime-test-cache-k
  1549. X                         (1+ math-prime-test-cache-k)
  1550. X                         math-prime-test-cache-q
  1551. X                         (math-div2
  1552. X                          math-prime-test-cache-q)))
  1553. X                     (setq iters (1+ iters))
  1554. X                     (list 'maybe
  1555. X                       0
  1556. X                       (math-sub
  1557. X                        100
  1558. X                        (math-div
  1559. X                         '(float 232 0)
  1560. X                         (math-numdigs n))))))))))
  1561. X          ((not (eq (car (nth 1 math-prime-test-cache)) 'maybe))
  1562. X           (nth 1 math-prime-test-cache))
  1563. X          (t   ; Fermat step
  1564. X           (let* ((x (math-add (calcFunc-random (math-add n -2)) 2))
  1565. X              (y (math-pow-mod x math-prime-test-cache-q n))
  1566. X              (j 0))
  1567. X             (while (and (not (eq y 1))
  1568. X                 (not (equal y math-prime-test-cache-nm1))
  1569. X                 (< (setq j (1+ j)) math-prime-test-cache-k))
  1570. X               (setq y (math-mod (math-mul y y) n)))
  1571. X             (if (or (equal y math-prime-test-cache-nm1)
  1572. X                 (and (eq y 1) (eq j 0)))
  1573. X             (list 'maybe
  1574. X                   (1+ (nth 1 (nth 1 math-prime-test-cache)))
  1575. X                   (math-mul (nth 2 (nth 1 math-prime-test-cache))
  1576. X                     '(float 25 -2)))
  1577. X               '(nil unknown))))))
  1578. X      (setq math-prime-test-cache (list n res)
  1579. X        iters (if (eq (car res) 'maybe)
  1580. X              (1- iters)
  1581. X            0)))
  1582. X    res)
  1583. )
  1584. (defvar math-prime-test-cache '(-1))
  1585. X
  1586. (defun calcFunc-prime (n &optional iters)
  1587. X  (or (math-num-integerp n) (math-reject-arg n 'integerp))
  1588. X  (or (not iters) (math-num-integerp iters) (math-reject-arg iters 'integerp))
  1589. X  (if (car (math-prime-test (math-trunc n) (math-trunc (or iters 1))))
  1590. X      1
  1591. X    0)
  1592. )
  1593. X
  1594. ;;; Theory: summing base-10^6 digits modulo 111111 is "casting out 999999s".
  1595. ;;; Initial probability that N is prime is 1/ln(N) = log10(e)/log10(N).
  1596. ;;; After culling [2,3,5,7,11,13,37], probability of primality is 5.36 x more.
  1597. ;;; Initial reported probability of non-primality is thus 100% - this.
  1598. ;;; Each Fermat step multiplies this probability by 25%.
  1599. ;;; The Fermat step is algorithm P from Knuth section 4.5.4.
  1600. X
  1601. X
  1602. (defun calcFunc-prfac (n)
  1603. X  (setq math-prime-factors-finished t)
  1604. X  (if (Math-messy-integerp n)
  1605. X      (setq n (math-trunc n)))
  1606. X  (if (Math-natnump n)
  1607. X      (if (Math-natnum-lessp 2 n)
  1608. X      (let (factors res p (i 0))
  1609. X        (while (and (not (eq n 1))
  1610. X            (< i (length math-primes-table)))
  1611. X          (setq p (aref math-primes-table i))
  1612. X          (while (eq (cdr (setq res (cond ((eq n p) (cons 1 0))
  1613. X                          ((eq n 1) (cons 0 1))
  1614. X                          ((consp n) (math-idivmod n p))
  1615. X                          (t (cons (/ n p) (% n p))))))
  1616. X             0)
  1617. X        (math-working "factor" p)
  1618. X        (setq factors (nconc factors (list p))
  1619. X              n (car res)))
  1620. X          (or (eq n 1)
  1621. X          (Math-natnum-lessp p (car res))
  1622. X          (setq factors (nconc factors (list n))
  1623. X            n 1))
  1624. X          (setq i (1+ i)))
  1625. X        (or (setq math-prime-factors-finished (eq n 1))
  1626. X        (setq factors (nconc factors (list n))))
  1627. X        (cons 'vec factors))
  1628. X    (list 'vec n))
  1629. X    (if (Math-integerp n)
  1630. X    (if (eq n -1)
  1631. X        (list 'vec n)
  1632. X      (cons 'vec (cons -1 (cdr (calcFunc-prfac (math-neg n))))))
  1633. X      (calc-record-why 'integerp n)
  1634. X      (list 'calcFunc-prfac n)))
  1635. )
  1636. X
  1637. (defun calcFunc-totient (n)
  1638. X  (if (Math-messy-integerp n)
  1639. X      (setq n (math-trunc n)))
  1640. X  (if (Math-natnump n)
  1641. X      (if (Math-natnum-lessp n 2)
  1642. X      (if (Math-negp n)
  1643. X          (calcFunc-totient (math-abs n))
  1644. X        n)
  1645. X    (let ((factors (cdr (calcFunc-prfac n)))
  1646. X          p)
  1647. X      (if math-prime-factors-finished
  1648. X          (progn
  1649. X        (while factors
  1650. X          (setq p (car factors)
  1651. X            n (math-mul (math-div n p) (math-add p -1)))
  1652. X          (while (equal p (car factors))
  1653. X            (setq factors (cdr factors))))
  1654. X        n)
  1655. X        (calc-record-why "*Number too big to factor" n)
  1656. X        (list 'calcFunc-totient n))))
  1657. X    (calc-record-why 'natnump n)
  1658. X    (list 'calcFunc-totient n))
  1659. )
  1660. X
  1661. (defun calcFunc-moebius (n)
  1662. X  (if (Math-messy-integerp n)
  1663. X      (setq n (math-trunc n)))
  1664. X  (if (and (Math-natnump n) (not (eq n 0)))
  1665. X      (if (Math-natnum-lessp n 2)
  1666. X      (if (Math-negp n)
  1667. X          (calcFunc-moebius (math-abs n))
  1668. X        1)
  1669. X    (let ((factors (cdr (calcFunc-prfac n)))
  1670. X          (mu 1))
  1671. X      (if math-prime-factors-finished
  1672. X          (progn
  1673. X        (while factors
  1674. X          (setq mu (if (equal (car factors) (nth 1 factors))
  1675. X                   0 (math-neg mu))
  1676. X            factors (cdr factors)))
  1677. X        mu)
  1678. X        (calc-record-why "Number too big to factor" n)
  1679. X        (list 'calcFunc-moebius n))))
  1680. X    (calc-record-why 'posintp n)
  1681. X    (list 'calcFunc-moebius n))
  1682. )
  1683. X
  1684. X
  1685. (defun calcFunc-nextprime (n &optional iters)
  1686. X  (if (Math-integerp n)
  1687. X      (if (Math-integer-negp n)
  1688. X      2
  1689. X    (if (and (integerp n) (< n 5003))
  1690. X        (math-next-small-prime (1+ n))
  1691. X      (if (math-evenp n)
  1692. X          (setq n (math-add n -1)))
  1693. X      (let (res)
  1694. X        (while (not (car (setq res (math-prime-test
  1695. X                    (setq n (math-add n 2))
  1696. X                    (or iters 1))))))
  1697. X        (if (and calc-verbose-nextprime
  1698. X             (eq (car res) 'maybe))
  1699. X        (calc-report-prime-test res)))
  1700. X      n))
  1701. X    (if (Math-realp n)
  1702. X    (calcFunc-nextprime (math-trunc n) iters)
  1703. X      (math-reject-arg n 'integerp)))
  1704. )
  1705. (setq calc-verbose-nextprime nil)
  1706. X
  1707. (defun calcFunc-prevprime (n &optional iters)
  1708. X  (if (Math-integerp n)
  1709. X      (if (Math-lessp n 4)
  1710. X      2
  1711. X    (if (math-evenp n)
  1712. X        (setq n (math-add n 1)))
  1713. X    (let (res)
  1714. X      (while (not (car (setq res (math-prime-test
  1715. X                      (setq n (math-add n -2))
  1716. X                      (or iters 1))))))
  1717. X      (if (and calc-verbose-nextprime
  1718. X           (eq (car res) 'maybe))
  1719. X          (calc-report-prime-test res)))
  1720. X    n)
  1721. X    (if (Math-realp n)
  1722. X    (calcFunc-prevprime (math-ceiling n) iters)
  1723. X      (math-reject-arg n 'integerp)))
  1724. )
  1725. X
  1726. (defun math-next-small-prime (n)
  1727. X  (if (and (integerp n) (> n 2))
  1728. X      (let ((lo -1)
  1729. X        (hi (length math-primes-table))
  1730. X        mid)
  1731. X    (while (> (- hi lo) 1)
  1732. X      (if (> n (aref math-primes-table
  1733. X             (setq mid (ash (+ lo hi) -1))))
  1734. X          (setq lo mid)
  1735. X        (setq hi mid)))
  1736. X    (aref math-primes-table hi))
  1737. X    2)
  1738. )
  1739. X
  1740. (defconst math-primes-table
  1741. X  [2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89
  1742. X     97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181
  1743. X     191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277
  1744. X     281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383
  1745. X     389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487
  1746. X     491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601
  1747. X     607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709
  1748. X     719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827
  1749. X     829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947
  1750. X     953 967 971 977 983 991 997 1009 1013 1019 1021 1031 1033 1039 1049
  1751. X     1051 1061 1063 1069 1087 1091 1093 1097 1103 1109 1117 1123 1129 1151
  1752. X     1153 1163 1171 1181 1187 1193 1201 1213 1217 1223 1229 1231 1237 1249
  1753. X     1259 1277 1279 1283 1289 1291 1297 1301 1303 1307 1319 1321 1327 1361
  1754. X     1367 1373 1381 1399 1409 1423 1427 1429 1433 1439 1447 1451 1453 1459
  1755. X     1471 1481 1483 1487 1489 1493 1499 1511 1523 1531 1543 1549 1553 1559
  1756. X     1567 1571 1579 1583 1597 1601 1607 1609 1613 1619 1621 1627 1637 1657
  1757. X     1663 1667 1669 1693 1697 1699 1709 1721 1723 1733 1741 1747 1753 1759
  1758. X     1777 1783 1787 1789 1801 1811 1823 1831 1847 1861 1867 1871 1873 1877
  1759. X     1879 1889 1901 1907 1913 1931 1933 1949 1951 1973 1979 1987 1993 1997
  1760. X     1999 2003 2011 2017 2027 2029 2039 2053 2063 2069 2081 2083 2087 2089
  1761. X     2099 2111 2113 2129 2131 2137 2141 2143 2153 2161 2179 2203 2207 2213
  1762. X     2221 2237 2239 2243 2251 2267 2269 2273 2281 2287 2293 2297 2309 2311
  1763. X     2333 2339 2341 2347 2351 2357 2371 2377 2381 2383 2389 2393 2399 2411
  1764. X     2417 2423 2437 2441 2447 2459 2467 2473 2477 2503 2521 2531 2539 2543
  1765. X     2549 2551 2557 2579 2591 2593 2609 2617 2621 2633 2647 2657 2659 2663
  1766. X     2671 2677 2683 2687 2689 2693 2699 2707 2711 2713 2719 2729 2731 2741
  1767. X     2749 2753 2767 2777 2789 2791 2797 2801 2803 2819 2833 2837 2843 2851
  1768. X     2857 2861 2879 2887 2897 2903 2909 2917 2927 2939 2953 2957 2963 2969
  1769. X     2971 2999 3001 3011 3019 3023 3037 3041 3049 3061 3067 3079 3083 3089
  1770. X     3109 3119 3121 3137 3163 3167 3169 3181 3187 3191 3203 3209 3217 3221
  1771. X     3229 3251 3253 3257 3259 3271 3299 3301 3307 3313 3319 3323 3329 3331
  1772. X     3343 3347 3359 3361 3371 3373 3389 3391 3407 3413 3433 3449 3457 3461
  1773. X     3463 3467 3469 3491 3499 3511 3517 3527 3529 3533 3539 3541 3547 3557
  1774. X     3559 3571 3581 3583 3593 3607 3613 3617 3623 3631 3637 3643 3659 3671
  1775. X     3673 3677 3691 3697 3701 3709 3719 3727 3733 3739 3761 3767 3769 3779
  1776. SHAR_EOF
  1777. true || echo 'restore of calc-comb.el failed'
  1778. fi
  1779. echo 'End of  part 10'
  1780. echo 'File calc-comb.el is continued in part 11'
  1781. echo 11 > _shar_seq_.tmp
  1782. exit 0
  1783. exit 0 # Just in case...
  1784. -- 
  1785. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1786. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1787. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1788. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1789.