+." $Header: ch3.n,v 1.3 83/06/21 13:00:48 sklower Exp $
+.Lc Arithmetic\ Functions 3
+.pp
+This chapter describes
+.Fr "'s"
+functions for doing arithmetic.
+Often the same function is known by many names.
+For example,
+.i add
+is also
+.i plus ,
+and
+.i sum .
+This is caused by our desire to be compatible with other Lisps.
+The
+.Fr
+user should avoid using functions with names
+such as \(pl and \(** unless
+their arguments are fixnums.
+The Lisp compiler takes advantage of these implicit declarations.
+.pp
+An attempt to divide or to generate a floating
+point result outside of the range of
+floating point numbers
+will cause a floating exception signal
+from the UNIX operating system.
+The user can catch and process this interrupt if desired (see the
+description of the
+.i signal
+function).
+.sh 2 Simple\ Arithmetic\ Functions \n(ch 1
+.Lf add "['n_arg1 ...]"
+.Lx plus "['n_arg1 ...]"
+.Lx sum "['n_arg1 ...]"
+.Lx \(pl "['x_arg1 ...]"
+.Re
+the sum of the arguments. If no arguments are given, 0 is returned.
+.No
+if the size of the partial sum exceeds the limit of a fixnum, the
+partial sum will be converted to a bignum.
+If any of the arguments are flonums, the partial sum will be
+converted to a flonum when that argument is processed and the
+result will thus be a flonum.
+Currently, if in the process of doing the
+addition a bignum must be converted into
+a flonum an error message will result.
+.Lf add1 'n_arg
+.Lx 1+ 'x_arg
+.Re
+its argument plus 1.
+.Lf diff "['n_arg1 ... ]"
+.Lx difference "['n_arg1 ... ]"
+.Lx \(mi "['x_arg1 ... ]"
+.Re
+the result of subtracting from n_arg1 all subsequent arguments.
+If no arguments are given, 0 is returned.
+.No
+See the description of add for details on data type conversions and
+restrictions.
+.Lf sub1 "'n_arg"
+.Lx 1\(mi "'x_arg"
+.Re
+its argument minus 1.
+.Lf minus "'n_arg"
+.Re
+zero minus n_arg.
+.Lf product "['n_arg1 ... ]"
+.Lx times "['n_arg1 ... ]"
+.Lx \(** "['x_arg1 ... ]"
+.Re
+the product of all of its arguments.
+It returns 1 if there are no arguments.
+.No
+See the description of the function \fIadd\fP for details and restrictions to the
+automatic data type coercion.
+.Lf quotient "['n_arg1 ...]"
+.Lx / "['x_arg1 ...]"
+.Re
+the result of dividing the first argument by succeeding ones.
+.No
+If there are no arguments, 1 is returned.
+See the description of the function \fIadd\fP for details and restrictions
+of data type coercion.
+A divide by zero will cause a floating exception interrupt -- see
+the description of the
+.i signal
+function.
+.Lf *quo "'i_x 'i_y"
+.Re
+the integer part of i_x / i_y.
+.Lf Divide "'i_dividend 'i_divisor"
+.Re
+a list whose car is the quotient and whose cadr is the remainder of the
+division of i_dividend by i_divisor.
+.No
+this is restricted to integer division.
+.Lf Emuldiv "'x_fact1 'x_fact2 'x_addn 'x_divisor"
+.Re
+a list of the quotient and remainder of this operation:
+((x_fact1\ *\ x_fact2)\ +\ (sign\ extended)\ x_addn)\ /\ x_divisor.
+.No
+this is useful for creating a bignum arithmetic package in Lisp.
+.sh 2 predicates
+.Lf numberp "'g_arg"
+.Lf numbp "'g_arg"
+.Re
+t iff g_arg is a number (fixnum, flonum or bignum).
+.Lf fixp "'g_arg"
+.Re
+t iff g_arg is a fixnum or bignum.
+.Lf floatp "'g_arg"
+.Re
+t iff g_arg is a flonum.
+.Lf evenp "'x_arg"
+.Re
+t iff x_arg is even.
+.Lf oddp "'x_arg"
+.Re
+t iff x_arg is odd.
+.Lf zerop "'g_arg"
+.Re
+t iff g_arg is a number equal to 0.
+.Lf onep "'g_arg"
+.Re
+t iff g_arg is a number equal to 1.
+.Lf plusp "'n_arg"
+.Re
+t iff n_arg is greater than zero.
+.Lf minusp "'g_arg"
+.Re
+t iff g_arg is a negative number.
+.Lf greaterp "['n_arg1 ...]"
+.Lx > "'fx_arg1 'fx_arg2"
+.Lx >& "'x_arg1 'x_arg2"
+.Re
+t iff the arguments are in a strictly decreasing order.
+.No
+In functions
+.i greaterp
+and
+.i >
+the function
+.i difference
+is used to compare adjacent values.
+If any of the arguments are non-numbers, the error message will come
+from the
+.i difference
+function.
+The arguments to
+.i >
+must be fixnums or both flonums.
+The arguments to
+.i >&
+must both be fixnums.
+.Lf lessp "['n_arg1 ...]"
+.Lx < "'fx_arg1 'fx_arg2"
+.Lx <& "'x_arg1 'x_arg2"
+.Re
+t iff the arguments are in a strictly increasing order.
+.No
+In functions
+.i lessp
+and
+.i <
+the function \fIdifference\fP is used to compare adjacent values.
+If any of the arguments are non numbers, the error message will come
+from the \fIdifference\fP function.
+The arguments to
+.i <
+may be either fixnums or flonums but must be the same type.
+The arguments to
+.i <&
+must be fixnums.
+.Lf \(eq "'fx_arg1 'fx_arg2"
+.Lf \(eq& "'x_arg1 'x_arg2"
+.Re
+t iff the arguments have the same value.
+The arguments to \(eq must be the either both fixnums or both flonums.
+The arguments to \(eq& must be fixnums.
+.sh 2 Trignometric\ Functions
+.pp
+Some of these funtcions are taken from the host math library, and
+we take no further responsibility for their accuracy.
+.Lf cos "'fx_angle"
+.Re
+the (flonum) cosine of fx_angle (which is assumed to be in radians).
+.Lf sin "'fx_angle"
+.Re
+the sine of fx_angle (which is assumed to be in radians).
+.Lf acos "'fx_arg"
+.Re
+the (flonum) arc cosine of fx_arg in the range 0 to \(*p.
+.Lf asin "'fx_arg"
+.Re
+the (flonum) arc sine of fx_arg in the range \(mi\(*p/2 to \(*p/2.
+.Lf atan "'fx_arg1 'fx_arg2"
+.Re
+the (flonum) arc tangent of fx_arg1/fx_arg2 in the range -\(*p to \(*p.
+.sh 2 Bignum/Fixnum\ Manipulation
+.Lf haipart "bx_number x_bits"
+.Re
+a fixnum (or bignum) which contains
+the x_bits high bits of
+\fI(abs\ bx_number)\fP if x_bits is positive, otherwise
+it returns the \fI(abs\ x_bits)\fP low bits of \fI(abs\ bx_number)\fP.
+.Lf haulong "bx_number"
+.Re
+the number of significant bits in bx_number.
+.No
+the result is equal to the least integer greater to or equal to the
+base two logarithm of
+one plus the absolute value of bx_number.
+.Lf bignum-leftshift "bx_arg x_amount"
+.Re
+bx_arg shifted left by x_amount. If
+x_amount is negative, bx_arg will be shifted right by the magnitude of
+x_amount.
+.No
+If bx_arg is shifted right, it will be rounded to the nearest even number.
+.Lf sticky-bignum-leftshift "'bx_arg 'x_amount"
+.Re
+bx_arg shifted left by x_amount. If
+x_amount is negative, bx_arg will be shifted right by the magnitude of
+x_amount and rounded.
+.No
+sticky rounding is done this way: after shifting,
+the low order bit is changed to 1
+if any 1's were shifted off to the right.
+.sh 2 Bit\ Manipulation
+.Lf boole "'x_key 'x_v1 'x_v2 ..."
+.Re
+the result of the bitwise boolean operation as described in the following
+table.
+.No
+If there are more than 3 arguments, then evaluation proceeds left to
+right with each partial result becoming the new value of x_v1.
+That is,
+.br
+\ \ \ \ \ \fI(boole\ 'key\ 'v1\ 'v2\ 'v3)\ \(==\ (boole\ 'key\ (boole\ 'key\ 'v1\ 'v2)\ 'v3)\fP.
+.br
+In the following table, \(** represents bitwise and, \(pl represents
+bitwise or, \o'\(ci\(pl' represents bitwise xor and \(no represents
+bitwise negation and is the highest precedence operator.
+.ps 8
+.TS
+center box ;
+c s s s s s s s s
+c c c c c c c c c.
+(boole 'key 'x 'y)
+
+=
+key 0 1 2 3 4 5 6 7
+result 0 x \(** y \(no x \(** y y x \(** \(no y x x \o'\(ci\(pl' y x \(pl y
+
+common
+names and bitclear xor or
+
+_
+
+key 8 9 10 11 12 13 14 15
+result \(no (x \(pl y) \(no(x \o'\(ci\(pl' y) \(no x \(no x \(pl y \(no y x \(pl \(no y \(no x \(pl \(no y -1
+common
+names nor equiv implies nand
+.TE
+.ps 10
+.pp
+.Lf lsh "'x_val 'x_amt"
+.Re
+x_val shifted left by x_amt if x_amt is positive.
+If x_amt is negative, then
+.i lsh
+returns x_val shifted right by the magnitude if x_amt.
+.No
+This always returns a fixnum even for those numbers whose magnitude is
+so large that they would normally be represented as a bignum,
+i.e. shifter bits are lost.
+For more general bit shifters, see
+.i bignum-leftshift
+and
+.i sticky-bignum-leftshift.
+.Lf rot "'x_val 'x_amt"
+.Re
+x_val rotated left by x_amt if x_amt is positive.
+If x_amt is negative, then x_val is rotated right by the magnitude of x_amt.
+.sh 2 Other\ Functions
+.pp
+As noted above, some of the following functions are inherited from the
+host math library, with all their virtues and vices.
+.Lf abs 'n_arg
+.Lx absval 'n_arg
+.Re
+the absolute value of n_arg.
+.Lf exp "'fx_arg"
+.Re
+.i e
+raised to the fx_arg power (flonum) .
+.Lf expt "'n_base 'n_power"
+.Re
+n_base raised to the n_power power.
+.No
+if either of the arguments are flonums, the calculation will be done using
+.i log
+and
+.i exp .
+.Lf fact "'x_arg"
+.Re
+x_arg factorial. (fixnum or bignum)
+.Lf fix "'n_arg"
+.Re
+a fixnum as close as we can get to n_arg.
+.No
+\fIfix\fP will round down.
+Currently, if n_arg is a flonum larger
+than the size of a fixnum, this will fail.
+.Lf float "'n_arg"
+.Re
+a flonum as close as we can get to n_arg.
+.No
+if n_arg is a bignum larger than the maximum size of a flonum,
+then a floating exception will occur.
+.Lf log "'fx_arg"
+.Re
+the natural logarithm of fx_arg.
+.Lf max "'n_arg1 ... "
+.Re
+the maximum value in the list of arguments.
+.Lf min "'n_arg1 ... "
+.Re
+the minimum value in the list of arguments.
+.Lf mod "'i_dividend 'i_divisor"
+.Lx remainder "'i_dividend 'i_divisor"
+.Re
+the remainder when i_dividend is divided by i_divisor.
+.No
+The sign of the result will have the same sign as i_dividend.
+.Lf *mod "'x_dividend 'x_divisor"
+.Re
+the balanced representation of x_dividend modulo x_divisor.
+.No
+the range of the balanced representation is abs(x_divisor)/2 to
+(abs(x_divisor)/2) \(mi x_divisor + 1.
+.Lf random "['x_limit]"
+.Re
+a fixnum between 0 and x_limit \(mi 1 if x_limit is given.
+If x_limit is not given, any fixnum, positive or negative, might be
+returned.
+.Lf sqrt "'fx_arg"
+.Re
+the square root of fx_arg.