
3.1     Numbers and Arithmetic Functions
Most of the arithmetic functions in PSL expect numbers as arguments. In all cases an error
occurs if the parameter to an arithmetic function is not a number:
⋆⋆⋆⋆⋆  Non-numeric argument in arithmetic
Exceptions to the rule are noted.
The underlying machine arithmetic requires parameters to be either all integers or all floats. If a
function receives mixed types of arguments, integers are converted to floats before arithmetic
operations are performed. The range of numbers which can be represented by an integer is
different than that represented by a float. Because of this difference, a conversion
is not always possible; an unsuccessful attempt to convert may cause an error to be
signalled.
The mathlib package contains some useful mathematical functions.
3.1.1     Big Integers
Loading the ZBIG ZIB version of big integers, the optimal version for the particular architecture 
module redefines the basic arithmetic operations, including the logical operations, to permit
arbitrary precision (or ”bignum”) integer operations.
3.1.2     Conversion Between Integers and Floats
The conversions mentioned above can be done explicitly by the following functions. Other
functions which alter types can be found in Section 2.3.
(fix U:number): integer                                                                                               expr
Returns  the  integer  which  corresponds  to  the  truncated  value  of  U.  The
result  of  conversion  must  retain  all  significant  portions  of  U.  If  U  is  an
integer it is returned unchanged.
 
    1 lisp> (fix 2.1)
 
    2
 
    2 lisp> (fix -2.1)
 
    -2
(float U:number): float                                                                                                expr
The  float  corresponding  to  the  value  of  the  argument  U  is  returned.
Some  of  the  least  significant  digits  of  an  integer  may  be  lost  due  to  the
implementation of float. If U a float then it will be returned unchanged. If U
is too large to represent in float an error occurs.
 
    ⋆⋆⋆⋆⋆ Argument to FLOAT is too large
3.1.3     Arithmetic Operators
This section describes arithmetic functions in the library module numeric-ops. The names of
these functions are based upon mathematical notation.
There is a switch called fast-integers whose value has an effect on the compilation of
forms which contain applications of the functions described here. The documentation
assumes that the switch fast-integers is nil. When this switch is non-nil the compiler
will generate code which is very efficient. However, it is assumed that arguments
and results will be integers in the inum range. If this assumption is violated then at
best your code will not generate correct results, you may actually damage the PSL
system.
Common LISP operators
(= X:number Y:number): boolean                                                                             expr
Numeric Equal. True if the two arguments are numbers of the same type
and  same  value.  Unlike  the  Common  LISP  operator,  no  type  coercion  is
done, no error is signalled if one or both arguments are non-numeric, and
only two arguments are permitted. Instead, it is merely incorrect to supply a
non-numeric argument.
 
(/= X:number Y:number): boolean                                                                            expr
Numeric Not Equal. Nil if X and Y are numbers of equal type and value; t
if X and Y are numbers of unequal type or value. It is incorrect to supply a
non-numeric argument.
 
(< X:number Y:number): boolean                                                                             expr
Numeric Less Than. True if X is less than Y, regardless of type. An error is
signalled if either argument is not numeric.
 
(> X:number Y:number): boolean                                                                             expr
Numeric Greater Than. True if X is greater than Y, regardless of type. An
error is signalled if either argument is not numeric.
 
(<= X:number Y:number): boolean                                                                          expr
Numeric Less Than or Equal. True if X is less than or equal to Y, regardless
of numeric type. An error is signalled if either argument is not numeric.
 
(>= X:number Y:number): boolean                                                                          expr
Numeric Greater Than or Equal. True if X is greater than or equal to Y,
regardless of numeric type. An error is signalled if either argument is not
numeric.
 
(+ [N:number]): number                                                                                          macro
Numeric Addition. The value returned is the sum of all the arguments. The
arguments may be of any numeric type. An error is signalled if any argument
is not numeric. If supplied no arguments, the value is 0.
 
(– N:number [N:number]): number                                                                       macro
Numeric Minus or Subtraction. If given one argument, returns the negative
of  that  argument.  If  given  more  than  one  argument,  returns  the  result  of
successively  subtracting  succeeding  arguments  from  the  first  argument.
Signals  an  error  if  no  arguments  are  supplied  or  if  any  argument  is
non-numeric.
 
(* [N:number]): number                                                                                          macro
Numeric  Multiplication.  The  value  returned  is  the  product  of  all  the
arguments. The arguments may be of any numeric type. An error is signalled
if any argument is not numeric. If supplied no arguments, the value is 1.
 
(/ N:number [N:number]): number                                                                        macro
Numeric  Reciprocal  or  Division.  If  given  one  argument,  returns  the
reciprocal  of  that  argument.  If  given  more  than  one  argument,  returns
the  result  of  successively  dividing  succeeding  arguments  from  the  first
argument. Signals an error if no arguments are supplied or if any argument
is non-numeric.
 
Additional Operators
(~= X:number Y:number): number                                                                         expr
Numeric Not Equal. Same as /=.
 
(// X:integer Y:integer): integer                                                                                  expr
Integer Remainder. Same as remainder.
 
(~ X:integer): integer                                                                                                  expr
Integer Bitwise Logical Not. Same as lnot.
 
(& X:integer Y:integer): integer                                                                                 expr
Integer Bitwise Logical And. Same as land.
 
(| X:integer Y:integer): integer                                                                                   expr
Integer Bitwise Logical Or. Same as lor.
 
(∧ X:integer Y:integer): integer                                                                                  expr
Integer Bitwise Logical Xor. Same as lxor.
 
(<< X:integer Y:integer): integer                                                                              expr
Integer Bitwise Logical Left Shift. Same as lshift.
 
(>> X:integer Y:integer): integer                                                                              expr
Integer Bitwise Logical Right Shift. Same as (lshift X (minus Y)).
 
3.1.4     Arithmetic Functions
The functions described below handle arithmetic operations. Please note the remarks at the
beginning of this Chapter regarding the mixing of argument types.
(abs U:number): number                                                                                            expr
Returns the absolute value of its argument.
 
(add1 U:number): number                                                                                         expr
Returns the value of U plus 1; the returned value is of the same type as U
(integer or float).
 
(decr U:form [Xi:number]): number                                                                      macro
This function is defined in the useful module. With only one argument, this
is equivalent to
 
    (setf u (sub1 u))
With multiple arguments, it is equivalent to
    (setf u (difference u (plus x1 ... xn)))
    1 lisp> (setq y '(1 5 7))
 
    (1 5 7)
 
    2 lisp> (decr (car y))
 
    0
 
    3 lisp> y
 
    (0 5 7)
 
    4 lisp> (decr (cadr y) 3 4)
 
    -2
 
    5 lisp> y
 
    (0 -2 7)
(difference U:number V:number): number                                                              expr
The value of U - V is returned.
 
(divide U:number V:number): pair                                                                            expr
The  pair  (quotient  .  remainder)  is  returned,  as  if  the  quotient  part  was
computed  by  the  quotient  function  and  the  remainder  by  the  remainder
function. An error occurs if division by zero is attempted:
 
    ⋆⋆⋆⋆⋆ Attempt to divide by 0 in Divide
(expt U:number V:integer): number                                                                          expr
Returns U raised to the V power. A float U to an integer power V does not
have V changed to a float before exponentiation.
 
(incr U:form [Xi:number]): number                                                                       macro
Part of the useful package. With only one argument, this is equivalent to
 
    (setf u (add1 u))
With multiple arguments it is equivalent to
    (setf u (plus u x1 ... xn))
(minus U:number): number                                                                                       expr
Returns -U.
 
(plus [U:number]): number                                                                                     macro
Forms  the  sum  of  all  its  arguments.  Plus  may  be  called  with  only  one
argument.  In  this  case  it  returns  its  argument.  If  plus  is  called  with  no
arguments, it returns zero.
 
(plus2 U:number V:number): number                                                                      expr
Returns the sum of U and V.
 
(quotient U:number V:number): number                                                                 expr
The quotient of U divided by V is returned. Division of two positive or two
negative integers is conventional. If both U and V are integers and exactly
one of them is negative, the value returned is truncated toward 0. If either
argument is a float, a float is returned which is exact within the implemented
precision of floats. An error occurs if division by zero is attempted:
 
    ⋆⋆⋆⋆⋆ Attempt to divide by 0 in QUOTIENT
(recip U:number): float                                                                                               expr
Recip converts U to a float if necessary, and then finds the inverse using the
function quotient.
 
(remainder U:integer V:integer): integer                                                                  expr
(- U (* V (fix (/ U (float V)))))
 
    (remainder 13 4)    =  1
 
    (remainder -13 4)   = -1
 
    (remainder 13 -4)   =  1
 
    (remainder -13 -4)  = -1
(sub1 U:number): number                                                                                          expr
Returns the value of U minus 1. If U is a float, the value returned is U minus
1.0.
 
(times [U:number]): number                                                                                   macro
Returns the product of all its arguments. Times may be called with only one
argument. In this case it returns the value of its argument. If times is called
with no arguments, it returns 1.
 
(times2 U:number V:number): number                                                                    expr
Returns the product of U and V.
 
3.1.5     Functions for Numeric Comparison
The following functions compare the values of their arguments. Functions which test for
equality and inequality are documented in Section 2.2.1.
(geq U:any V:any): boolean                                                                                        expr
Equivalent to (¿= U V).
 
(greaterp U:number V:number): boolean                                                                 expr
Equivalent to (¿ U V).
 
(leq U:number V:number): boolean                                                                           expr
Equivalent to (¡= U V).
 
(lessp U:number V:number): boolean                                                                       expr
Equivalent to (¡ U V).
 
(max [U:number]): number                                                                                     macro
Returns the largest of the values in U (numeric maximum). If two or more
values are the same, the first is returned.
 
(max2 U:number V:number): number                                                                      expr
Returns  the  larger  of  U  and  V.  If  U  and  V  are  of  the  same  value,  U  is
returned (U and V might be of different types).
 
(min [U:number]): number                                                                                      macro
Returns the smallest (numeric minimum), of the values in U. If two or more
values are the same, the first of these is returned.
 
(min2 U:number V:number): number                                                                       expr
Returns the smaller of its arguments. If U and V are the same value, U is
returned (U and V might be of different types).
 
(minusp U:any): boolean                                                                                             expr
Returns t if U is a number and less than 0. The return value is nil if U is not
a number, or if U is a positive number.
 
(onep U:any): boolean                                                                                                 expr
Returns t if U is a number and has the value 1 or 1.0. Returns nil otherwise.
 
(zerop U:any): boolean                                                                                                expr
Returns t if U is a number and has the value 0 or 0.0. Returns nil otherwise.
 
3.1.6     Bit Operations
The functions described in this section operate on the binary representation of the integers given
as arguments. The returned value is an integer.
(land U:integer V:integer): integer                                                                             expr
Bitwise or logical and. Each bit of the result is independently determined
from the corresponding bits of the operands.
 
(lor U:integer V:integer): integer                                                                               expr
Bitwise or logical or. Each bit of the result is independently determined
from corresponding bits of the operands. This is an inclusive or, the value
of (lor 1 1) is 1.
 
(lnot U:integer): integer                                                                                              expr
Logical not. Defined as (- -U 1) so that it works for bignums as if they were
2’s complement.
 
(lxor U:integer V:integer): integer                                                                             expr
Bitwise or logical exclusive or, the value of (lxor 1 1) is 0. Each bit of
the result is independently determined from the corresponding bits of the
operands.
 
(lshift N:integer K:integer): integer                                                                           expr
Shifts N to the left by K bits. The effect is similar to multiplying by 2 to the
K power. Negative values are acceptable for K, and cause a right shift (in
the usual manner). Lshift is a logical shift, so right shifts do not resemble
division by a power of 2.
 
3.1.7     Various Mathematical Functions
The optionally loadable mathlib module defines several commonly used mathematical
functions. Some effort has been made to be compatible with Common Lisp. When
reading the examples, note that the precision of the results depend on the machine being
used.
(ceiling X:number): integer                                                                                        expr
Returns the smallest integer greater than or equal to X. For example:
 
    1 lisp> (ceiling 2.1)
 
    3
 
    2 lisp> (ceiling -2.1)
 
    -2
(floor X:number): integer                                                                                           expr
Returns the largest integer less than or equal to X. (Note that this differs
from the fix function.)
 
    1 lisp> (floor 2.1)
 
    2
 
    2 lisp> (floor -2.1)
 
    -3
 
    3 lisp> (fix -2.1)
 
    -2
(round X:number): integer                                                                                         expr
Returns the nearest integer to X. If the fractional part of X is 0.5 then the
smaller integer is returned.
 
    (de round (x)
 
      (if (fixp x) x (floor (plus x 0.5))))
    1 lisp> (round 2.5)
 
    3
 
    2 lisp> (round -2.5)
 
    -2
(transfersign S:number VAL:number): number                                                      expr
Transfers the sign of S to VAL.
 
    (de transfersign (s val)
 
      (if (>= s 0) (abs val) (minus (abs val))))
(mod M:integer N:integer): integer                                                                           expr
(- U (* V (floor (/ U (float V)))))
 
    (mod 13 4)    =  1
 
    (mod -13 4)   =  3
 
    (mod 13 -4)   = -3
 
    (mod -13 -4)  = -1
(degreestoradians X:number): number                                                                     expr
Returns an angle in radians given an angle in degrees.
 
    1 lisp> (degreestoradians 180)
 
    3.1415926
(radianstodegrees X:number): number                                                                     expr
Returns an angle in degrees given an angle in radians.
 
    1 lisp> (radianstodegrees 3.1415926)
 
    180.0
(radianstodms X:number): list                                                                                   expr
Given an angle X in radians, returns a list of three integers, which represent
the degrees, minutes, and seconds.
 
    1 lisp> (radianstodms 1.0)
 
    (57 17 45)
(dmstoradians Degs:number Mins:number Secs:number): number                     expr
Returns an angle in radians, given three arguments representing an angle in
degrees minutes and seconds.
 
    1 lisp> (dmstoradians 57 17 45)
 
    1.0000009
 
    2 lisp> (dmstoradians 180 0 0)
 
    3.1415926
(degreestodms X:number): list                                                                                   expr
Given an angle X in degrees, returns a list of three integers giving the angle
in (Degrees Minutes Seconds).
 
(dmstodegrees Degs:number Mins:number Secs:number): number                      expr
Returns an angle in degrees, given three arguments representing an angle
in degrees minutes and seconds.
 
(sin X:number): number                                                                                             expr
Returns the sine of X, an angle in radians.
 
(sind X:number): number                                                                                           expr
Returns the sine of X, an angle in degrees.
 
(cos X:number): number                                                                                             expr
Returns the cosine of X, an angle in radians.
 
(cosd X:number): number                                                                                          expr
Returns the cosine of X, an angle in degrees.
 
(tan X:number): number                                                                                            expr
Returns the tangent of X, an angle in radians.
 
(tand X:number): number                                                                                          expr
Returns the tangent of X, an angle in degrees.
 
(cot X:number): number                                                                                             expr
Returns the cotangent of X, an angle in radians.
 
(cotd X:number): number                                                                                           expr
Returns the cotangent of X, an angle in degrees.
 
(sec X:number): number                                                                                             expr
Returns the secant of X, an angle in radians.
 
(secd X:number): number                                                                                           expr
Returns the secant of X, an angle in degrees.
 
(csc X:number): number                                                                                             expr
Returns the cosecant of X, an angle in radians.
 
(cscd X:number): number                                                                                           expr
Returns the cosecant of X, an angle in degrees.
 
(asin X:number): number                                                                                           expr
Returns the arc sine, as an angle in radians, of X.
 
    (eqn (sin (asin X)) X)
(asind X:number): number                                                                                         expr
Returns the arc sine, as an angle in degrees, of X.
 
(acos X:number): number                                                                                           expr
Returns the arc cosine, as an angle in radians, of X.
 
    (eqn (cos (acos X)) X)
(acosd X:number): number                                                                                        expr
Returns the arc cosine, as an angle in degrees, of X.
 
(atan X:number): number                                                                                          expr
Returns the arc tangent, as an angle in radians, of X.
 
    (eqn (tan (atan X)) X)
(atand X:number): number                                                                                        expr
Returns the arc tangent, as an angle in degrees, of X.
 
(atan2 Y:number X:number): number                                                                      expr
Returns an angle in radians corresponding to the angle between the X axis
and the vector [X Y]. Note that Y is the first argument.
 
    1 lisp> (atan2 0 -1)
 
    3.1415927
(atan2d Y:number X:number): number                                                                    expr
Returns an angle in degrees corresponding to the angle between the X axis
and the vector [X Y].
 
    1 lisp> (atan2d -1 1)
 
    315.0
(acot X:number): number                                                                                           expr
Returns the arc cotangent, as an angle in radians, of X.
 
    (eqn (cot (acot X)) X)
(acotd X:number): number                                                                                         expr
Returns the arc cotangent, as an angle in degrees, of X.
 
(asec X:number): number                                                                                           expr
Returns the arc secant, as an angle in radians, of X.
 
    (eqn (sec (asec X)) X)
(asecd X:number): number                                                                                         expr
Returns the arc secant, as an angle in degrees, of X.
 
(acsc X:number): number                                                                                           expr
Returns the arc cosecant, as an angle in radians, of X.
 
    (eqn (csc (acsc X)) X)
(acscd X:number): number                                                                                         expr
Returns the arc cosecant, as an angle in degrees, of X.
 
(sqrt X:number): number                                                                                           expr
Returns the square root of X.
 
(exp X:number): number                                                                                            expr
Returns the exponential of X.
 
(log X:number): number                                                                                             expr
Returns the natural (base e) logarithm of X. note that (log (log (exp X)) is
equal to X.
 
(log2 X:number): number                                                                                           expr
Returns the base two logarithm of X.
 
(log10 X:number): number                                                                                         expr
Returns the base ten logarithm of X.
 
(random N:integer): integer                                                                                       expr
Returns a pseudo-random number uniformly selected from the range 0 ...
(sub1 N).
 
The random number generator uses a linear congruential method.
randomseed = Initially: set from time                                                                       
global
         To get a reproducible sequence of random numbers you should assign one
(or some other small number) to the fluid variable randomseed.
 
(factorial N:integer): integer                                                                                       expr
The factorial function is defined as follows
 
      1. The factorial of 0 is 1.
      2. The factorial of N is N times the factorial of N-1.
    (de factorial (n)
 
      (if (zerop n) 1 (⋆ n (factorial (sub1 n)))))