\" Copyright (c) 1980 Regents of the University of California.
\" All rights reserved.  The Berkeley software License Agreement
\" specifies the terms and conditions for redistribution.
\"
\"      @(#)ch3.n       6.2 (Berkeley) 5/14/86
\"
" $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
(b
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
)b
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.