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)))))