document distributed with 4.3BSD
authorNick Cuccia <cuccia@ucbvax.Berkeley.EDU>
Wed, 30 Apr 1986 10:07:30 +0000 (02:07 -0800)
committerNick Cuccia <cuccia@ucbvax.Berkeley.EDU>
Wed, 30 Apr 1986 10:07:30 +0000 (02:07 -0800)
SCCS-vsn: old/lisp/PSD.doc/ch3.n 6.1

usr/src/old/lisp/PSD.doc/ch3.n

index 432d6f7..a3daf2b 100644 (file)
@@ -2,5 +2,354 @@
 .\" All rights reserved.  The Berkeley software License Agreement
 .\" specifies the terms and conditions for redistribution.
 .\"
 .\" All rights reserved.  The Berkeley software License Agreement
 .\" specifies the terms and conditions for redistribution.
 .\"
-.\"    @(#)ch3.n       5.1 (Berkeley) %G%
+.\"    @(#)ch3.n       6.1 (Berkeley) %G%
 .\"
 .\"
+." $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.