3.11 Arithmetic Functions

Conversions between numeric types are provided explicitly by the FIX and FLOAT functions and implicitly by any multi-parameter arithmetic function which receives mixed types of arguments. A conversion from fixed to floating point numbers may result in a loss of precision without a warning message being generated. Since integers may have a greater magnitude that that permitted for floating numbers, an error may be signaled when the attempted conversion cannot be done. Because the magnitude of integers is unlimited the conversion of a floating point number to a fixed number is always possible, the only loss of precision being the digits to the right of the decimal point which are truncated. If a function receives mixed types of arguments the general rule will have the fixed numbers converted to floating before arithmetic operations are performed. In all cases an error occurs if the parameter to an arithmetic function is not a number:

***** XXX parameter to FUNCTION is not a number

XXX is the value of the parameter at fault and FUNCTION is the name of the function that detected the error. Exceptions to the rule are noted where they occur.

ABS(U:number):number eval, spread
 
Returns the absolute value of its argument.
EXPR PROCEDURE ABS(U);

  IF LESSP(U, 0) THEN MINUS(U) ELSE U;

ADD1(U:number):number eval, spread
 
Returns the value of U plus 1 of the same type as U (fixed or floating).
EXPR PROCEDURE ADD1(U);

  PLUS2(U, 1);

DIFFERENCE(U:number, V:number):number eval, spread
 
The value U - V is returned.

DIVIDE(U:number, V:number):dotted-pair eval, spread
 
The dotted-pair (quotient . remainder) is returned. The quotient part is computed the same as by QUOTIENT and the remainder the same as by REMAINDER. An error occurs if division by zero is attempted:

***** Attempt to divide by 0 in DIVIDE

EXPR PROCEDURE DIVIDE(U, V);

  (QUOTIENT(U, V) . REMAINDER(U, V));

EXPT(U:number, V:integer):number eval, spread
 
Returns U raised to the V power. A floating point U to an integer power V does not have V changed to a floating number before exponentiation.

FIX(U:number):integer eval, spread
 
Returns an 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.

FLOAT(U:number):floating eval, spread
 
The floating point number corresponding to the value of the argument U is returned. Some of the least significant digits of an integer may be lost do to the implementation of floating point numbers. FLOAT of a floating point number returns the number unchanged. If U is too large to represent in floating point an error occurs:

***** Argument to FLOAT is too large

GREATERP(U:number, V:number):boolean eval, spread
 
Returns T if U is strictly greater than V, otherwise returns NIL.

LESSP(U:number, V:number):boolean eval, spread
 
Returns T if U is strictly less than V, otherwise returns NIL.

MAX([U:number]):number noeval, nospread, or macro
 
Returns the largest of the values in U. If two or more values are the same the first is returned.
MACRO PROCEDURE MAX(U);

  EXPAND(CDR U, ’MAX2);

MAX2(U:number, V:number):number eval, spread
 
Returns the larger of U and V. If U and V are the same value U is returned (U and V might be of different types).
EXPR PROCEDURE MAX2(U, V);

  IF LESSP(U, V) THEN V ELSE U;

MIN([U:number]):number noeval, nospread, or macro
 
Returns the smallest of the values in U. If two or more values are the same the first of these is returned.
MACRO PROCEDURE MIN(U);

  EXPAND(CDR U, ’MIN2);

MIN2(U:number, V:number):number eval, spread
 
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).
EXPR PROCEDURE MIN2(U, V);

  IF GREATERP(U, V) THEN V ELSE U;

MINUS(U:number):number eval, spread
 
Returns -U.
EXPR PROCEDURE MINUS(U);

  DIFFERENCE(0, U);

PLUS([U:number]):number noeval, nospread, or macro
 
Forms the sum of all its arguments.
MACRO PROCEDURE PLUS(U);

  EXPAND(CDR U, ’PLUS2);

PLUS2(U:number, V:number):number eval, spread
 
Returns the sum of U and V.

QUOTIENT(U:number, V:number):number eval, spread
 
The quotient of U divided by V is returned. Division of two positive or two negative integers is conventional. When both U and V are integers and exactly one of them is negative the value returned is the negative truncation of the absolute value of U divided by the absolute value of V. An error occurs if division by zero is attempted:

***** Attempt to divide by 0 in QUOTIENT

REMAINDER(U:number, V:number):number eval, spread
 
If both U and V are integers the result is the integer remainder of U divided by V. If either parameter is floating point, the result is the difference between U and V*(U/V) all in floating point. If either number is negative the remainder is negative. If both are positive or both are negative the remainder is positive. An error occurs if V is zero:

***** Attempt to divide by 0 in REMAINDER

EXPR PROCEDURE REMAINDER(U, V);

  DIFFERENCE(U, TIMES2(QUOTIENT(U, V), V));

SUB1(U:number):number eval, spread
 
Returns the value of U less 1. If U is a FLOAT type number, the value returned is U less 1.0.
EXPR PROCEDURE SUB1(U);

  DIFFERENCE(U, 1);

TIMES([U:number]):number noeval, nospread, or macro
 
Returns the product of all its arguments.
MACRO PROCEDURE TIMES(U);

  EXPAND(CDR U, ’TIMES2);

TIMES2(U:number, V:number):number eval, spread
 
Returns the product of U and V.