xref: /original-bsd/old/lisp/PSD.doc/ch3.n (revision a5a45b47)
Copyright (c) 1980 The Regents of the University of California.
All rights reserved.

%sccs.include.redist.roff%

@(#)ch3.n 6.3 (Berkeley) 04/17/91

." $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 - "['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- "'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 add 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 add 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 difference is used to compare adjacent values. If any of the arguments are non numbers, the error message will come from the difference 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 -\(*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 (abs bx_number) if x_bits is positive, otherwise it returns the (abs x_bits) low bits of (abs bx_number). .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,

(boole 'key 'v1 'v2 'v3) \(== (boole 'key (boole 'key 'v1 'v2) 'v3).

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. .(b

(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
.)b .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 fix 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) - x_divisor + 1. .Lf random "['x_limit]" .Re a fixnum between 0 and x_limit - 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.