home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD1.bin
/
gnu
/
info
/
calc.info-26
(
.txt
)
< prev
next >
Wrap
GNU Info File
|
1994-12-22
|
46KB
|
805 lines
This is Info file calc.info, produced by Makeinfo-1.55 from the input
file calc.texinfo.
This file documents Calc, the GNU Emacs calculator.
Copyright (C) 1990, 1991 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.
Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided also
that the section entitled "GNU General Public License" is included
exactly as in the original, and provided that the entire resulting
derived work is distributed under the terms of a permission notice
identical to this one.
Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions, except that the section entitled "GNU General Public License"
may be included in a translation approved by the author instead of in
the original English.
File: calc.info, Node: Argument Qualifiers, Next: Example Definitions, Prev: Defining Stack Commands, Up: Lisp Definitions
Argument Qualifiers
-------------------
Anywhere a parameter name can appear in the parameter list you can also
use an "argument qualifier". Thus the general form of a definition is:
(defmath NAME (PARAM PARAM...
&optional PARAM PARAM...
&rest PARAM)
BODY)
where each PARAM is either a symbol or a list of the form
(QUAL PARAM)
The following qualifiers are recognized:
`complete'
The argument must not be an incomplete vector, interval, or
complex number. (This is rarely needed since the Calculator
itself will never call your function with an incomplete argument.
But there is nothing stopping your own Lisp code from calling your
function with an incomplete argument.)
`integer'
The argument must be an integer. If it is an integer-valued float
it will be accepted but converted to integer form. Non-integers
and formulas are rejected.
`natnum'
Like `integer', but the argument must be non-negative.
`fixnum'
Like `integer', but the argument must fit into a native Lisp
integer, which on most systems means less than 2^23 in absolute
value. The argument is converted into Lisp-integer form if
necessary.
`float'
The argument is converted to floating-point format if it is a
number or vector. If it is a formula it is left alone. (The
argument is never actually rejected by this qualifier.)
`PRED'
The argument must satisfy predicate PRED, which is one of the
standard Calculator predicates. *Note Predicates::.
`not-PRED'
The argument must *not* satisfy predicate PRED.
For example,
(defmath foo (a (constp (not-matrixp b)) &optional (float c)
&rest (integer d))
BODY)
expands to
(defun calcFunc-foo (a b &optional c &rest d)
(and (math-matrixp b)
(math-reject-arg b 'not-matrixp))
(or (math-constp b)
(math-reject-arg b 'constp))
(and c (setq c (math-check-float c)))
(setq d (mapcar 'math-check-integer d))
BODY)
which performs the necessary checks and conversions before executing the
body of the function.
File: calc.info, Node: Example Definitions, Next: Calling Calc from Your Programs, Prev: Argument Qualifiers, Up: Lisp Definitions
Example Definitions
-------------------
This section includes some Lisp programming examples on a larger scale.
These programs make use of some of the Calculator's internal functions;
*note Internals::..
* Menu:
* Bit Counting Example::
* Sine Example::
File: calc.info, Node: Bit Counting Example, Next: Sine Example, Prev: Example Definitions, Up: Example Definitions
Bit-Counting
............
Calc does not include a built-in function for counting the number of
"one" bits in a binary integer. It's easy to invent one using `b u' to
convert the integer to a set, and `V #' to count the elements of that
set; let's write a function that counts the bits without having to
create an intermediate set.
(defmath bcount ((natnum n))
(interactive 1 "bcnt")
(let ((count 0))
(while (> n 0)
(if (oddp n)
(setq count (1+ count)))
(setq n (lsh n -1)))
count))
When this is expanded by `defmath', it will become the following Emacs
Lisp function:
(defun calcFunc-bcount (n)
(setq n (math-check-natnum n))
(let ((count 0))
(while (math-posp n)
(if (math-oddp n)
(setq count (math-add count 1)))
(setq n (calcFunc-lsh n -1)))
count))
If the input numbers are large, this function involves a fair amount
of arithmetic. A binary right shift is essentially a division by two;
recall that Calc stores integers in decimal form so bit shifts must
involve actual division.
To gain a bit more efficiency, we could divide the integer into
n-bit chunks, each of which can be handled quickly because they fit
into Lisp integers. It turns out that Calc's arithmetic routines are
especially fast when dividing by an integer less than 1000, so we can
set n = 9 bits and use repeated division by 512:
(defmath bcount ((natnum n))
(interactive 1 "bcnt")
(let ((count 0))
(while (not (fixnump n))
(let ((qr (idivmod n 512)))
(setq count (+ count (bcount-fixnum (cdr qr)))
n (car qr))))
(+ count (bcount-fixnum n))))
(defun bcount-fixnum (n)
(let ((count 0))
(while (> n 0)
(setq count (+ count (logand n 1))
n (lsh n -1)))
count))
Note that the second function uses `defun', not `defmath'. Because
this function deals only with native Lisp integers ("fixnums"), it can
use the actual Emacs `+' and related functions rather than the slower
but more general Calc equivalents which `defmath' uses.
The `idivmod' function does an integer division, returning both the
quotient and the remainder at once. Again, note that while it might
seem that `(logand n 511)' and `(lsh n -9)' are more efficient ways to
split off the bottom nine bits of `n', actually they are less efficient
because each operation is really a division by 512 in disguise;
`idivmod' allows us to do the same thing with a single division by 512.
File: calc.info, Node: Sine Example, Prev: Bit Counting Example, Up: Example Definitions
The Sine Function
.................
A somewhat limited sine function could be defined as follows, using the
well-known Taylor series expansion for `sin(x)':
(defmath mysin ((float (anglep x)))
(interactive 1 "mysn")
(setq x (to-radians x)) ; Convert from current angular mode.
(let ((sum x) ; Initial term of Taylor expansion of sin.
newsum
(nfact 1) ; "nfact" equals "n" factorial at all times.
(xnegsqr :"-(x^2)")) ; "xnegsqr" equals -x^2.
(for ((n 3 100 2)) ; Upper limit of 100 is a good precaution.
(working "mysin" sum) ; Display "Working" message, if enabled.
(setq nfact (* nfact (1- n) n)
x (* x xnegsqr)
newsum (+ sum (/ x nfact)))
(if (~= newsum sum) ; If newsum is "nearly equal to" sum,
(break)) ; then we are done.
(setq sum newsum))
sum))
The actual `sin' function in Calc works by first reducing the problem
to a sine or cosine of a nonnegative number less than `pi/4'. This
ensures that the Taylor series will converge quickly. Also, the
calculation is carried out with two extra digits of precision to guard
against cumulative round-off in `sum'. Finally, complex arguments are
allowed and handled by a separate algorithm.
(defmath mysin ((float (scalarp x)))
(interactive 1 "mysn")
(setq x (to-radians x)) ; Convert from current angular mode.
(with-extra-prec 2 ; Evaluate with extra precision.
(cond ((complexp x)
(mysin-complex