The Revised Maclisp ManualThe PitmanualPage A-9
Published by HyperMeta Inc.
 
Prev | Index | Next
[Blue Marble]
Climate Change
Melting ice affects more than just coastal cities.


Numbers


NumbersConceptNumeric Data

There are three numeric datatypes in Maclisp: FIXNUM, FLONUM, and BIGNUM. Some functions which manipulate numbers may handle only one or two of these types. Check the documentation to be sure which kinds of numbers are acceptable.

Integers are broken into two classes in Maclisp: fixnums and bignums. The FIXP predicate returns true if its argument is either a fixnum or a bignum, and returns false otherwise.

Small integers are represented as fixed point binary numbers. Which integers are fixnums is a machine-dependent feature since word size varies between Maclisp implementations. The FIXNUMP predicate returns true iff its argument is a fixnum; it returns false for other kinds objects including flonums and bignums.

Integers whose magnitude is too large to be represented in a single machine word are called bignums. A bignum is an infinite-precision integer. It is impossible to get “overflow” in bignum arithmetic, since any integer can be represented by a bignum. However, fixnum and flonum arithmetic is faster than bignum arithmetic and requires less memory. The BIGP predicate returns true iff its argument is a bignum.

Non-integers (what some languages refer to as “real” numbers) are called flonums. They are also sometimes referred to as floating point numbers. They are represented internally as a base and an exponent according to the floating point storage strategy native to the hardware in any given implementation. Their precision and range of values is therefore machine dependent.

Integers (fixnums and flonums) are printed as a series of digits in the current output radix (controlled by the variable BASE). If the BASE is decimal and the value of the variable *NOPOINT is NIL, a decimal point is displayed as well to make it obvious that the output is decimal. If *NOPOINT is NIL and you don't see a period after an integer, then decimal output is not selected. For example, the number nine would be displayed as 11 in octal (Maclisp's default input and output radix); it would be displayed as 9 or 9. in decimal, depending on the setting of *NOPOINT; and it would be displayed as 21 in base four. A minus sign precedes negative integers; negative four is -4, for example.

Flonums are always displayed in decimal radix in spite of the setting of BASE. Flonums are displayed as at least one digit (frequently more than one), followed by a decimal point, followed by at least one digit. So the sequence 4.75 means four and three quarters. A minus sign, of course, will precede a negative number. Some flonums may be displayed in an alternate notation called “exponential form.” In this notation, the letter E follows the flonum and then an integer (with no decimal point) denoting the power of ten by which the flonum is to be multiplied. For example, 3.0E+5 and 300000.0 denote the same number.

To enter a number as input, you can basically just invert the printing technique described above. Note, however, that IBASE controls the default input radix and typing a decimal point after an integer forces decimal input regardless of the input radix. So, in base eight, the list (12 10.) contains two tens.

The EQ predicate is not guaranteed to return true for two numbers with the same sign and magnitude. It sometimes will, but frequently does not. When comparing two fixnums or two flonums, use the = predicate. When comparing two bignums, use EQUAL. When comparing numbers of differing datatypes for numerical equality, you must first coerce the numbers to be of the same datatype before calling EQUAL; otherwise, EQUAL will return NIL.

By the way, when dealing with very large flonums, it's worth noting that some flonums are too large to be able to accurately represent all their integral digits. On the PDP-10, to take an example, 1.0e+20 does not have 20 digits of accuracy. Hence, an operation like (ADD1 1.0e+20) will return 1.0e+20, which may confuse some algorithms if they are not expecting it.

Coercion


FIXFunction(FIX n)

Returns the largest integer less than or equal to its argument n. The argument, n, may be any type of number. The result will be a fixnum or bignum, depending on n's magnitude.

Examples:

(fix 7.3)		=>	 7
(fix -1.2)		=>	-2

IFIXFunction(IFIX k)

Returns the largest fixnum less than or equal to its argument, k, which must be a fixnum or flonum. For use when k is known to be small enough to be represented as a fixnum. When in doubt, use FIX.

Examples:

(ifix  3.0E5)	=>	 300000.
(ifix -250.3)	=>	-251.
(ifix 5)	=>	 5.

FLOATFunction(FLOAT n)

Returns the flonum equivalent of n. n may be any kind of number.

Example:

(float 4)	=>	4.0

Numerical Type Predicates


NUMBERPFunction(NUMBERP q)

Predicate returns true if q is a number (fixnum, bignum, or flonum); otherwise returns false. q may be any kind of object.

Examples:

(numberp 5000)		  => T	 ;a fixnum is a number
(numberp 100000000000000) => T   ;a bignum is a number
(numberp 3.7)		  => T   ;a flonum is a number
(numberp 3.0e+35)	  => T   ;ditto
(numberp 'hello)	  => NIL ;symbols aren't numbers

FIXNUMPFunction(FIXNUMP q)

Predicate returns true iff q is a fixnum; otherwise returns false. q may be any kind of object.

Examples:

(fixnump 5000)		  => T	 ;a fixnum
(fixnump 100000000000000) => NIL ;bignums aren't fixnums
(fixnump 3.7)		  => NIL ;flonums aren't fixnums
(fixnump 3.0e+35)	  => NIL ;ditto
(fixnump 'hello)	  => NIL ;symbols aren't fixnums

BIGPFunction(BIGP q)

Predicate returns true if q is a bignum; otherwise returns false. q may be any kind of object.

Examples:

(bigp 5000)		=> NIL ;fixnums aren't bignums
(bigp 100000000000000)	=> T   ;a bignum
(bigp 3.7)		=> NIL ;flonums aren't bignums
(bigp 3.0e+35)		=> NIL ;ditto
(bigp 'hello)		=> NIL ;symbols aren't bignums

FIXPFunction(FIXP q)

Predicate returns T if q is an integer (fixnum or bignum) and NIL otherwise.

Examples:

(fixp 5000)		=> T	;fixnums are integers
(fixp 100000000000000)	=> T	;bignums are integers
(fixp 3.7)		=> NIL	;flonums aren't integers
(fixp 3.0e+35)		=> NIL	;ditto
(fixp 'hello)		=> NIL	;symbols aren't integers

FLOATPFunction(FLOATP q)

Predicate returns true iff q is a flonum; otherwise returns false. q may be any kind of object.

Examples:

(floatp 5000)		 => NIL	;fixnums aren't flonums
(floatp 100000000000000) => NIL	;bignums aren't flonums
(floatp 3.7)		 => T	;a flonum
(floatp 3.0e+35)	 => T	;a flonum
(floatp 'hello)		 => NIL	;symbols aren't flonums

PLUSFunction(PLUS n1 n2 ...)

Plus returns the sum of its arguments, which may be any kind of numbers.

Examples:

(PLUS)		=>	0	;Identity Element
(PLUS 3)	=>	3	;Trivial Case
(PLUS 3 4)	=>	7	;fixnum+fixnum=fixnum
(PLUS 3.0 4.0)	=>	7.0	;flonum+flonum=flonum
(PLUS 100000000000 100000000000) 
                => 200000000000 ;bignum+bignum=bignum
(PLUS 3.0 4)	=>	7.0	;anything+flonum=flonum
(PLUS 1.0E+20 1)=>	1.0E+20	;not always precise
(PLUS 100000000000 1)
                => 100000000001 ;fixnum+bignum=bignum

+Function(+ i1 i2 ...)

Returns the sum of its arguments. The arguments must be fixnums and the result is always a fixnum. Overflow is ignored.

Examples:

(+)		=>	0	;identity element
(+ 3)		=>	3	;trivial case
(+ 2 6 -1)	=>	7

+$Function(+$ x1 x2 ...)

Returns the sum of its arguments. The arguments must be flonums and the result is always a flonum.

Examples:

(+$ 4.1 3.14)		=>	 7.24
(+$ 2.0 1.5 -3.6)	=>	-0.1
(+$ 2.6)		=>	 2.6	;trivial case
(+$)			=>	 0.0	;identity element

ADD1Function(ADD1 n)

Exactly equivalent to (PLUS n 1).


1+Function(1+ i)

Exactly equivalent to (+ i 1).


1+$Function(1+$ x)

Exactly equivalent to (+$ x 1.0).


DIFFERENCEFunction(DIFFERENCE n1 n2 ...)

Returns its n1 minus the rest of its arguments. It works for any kind of numbers.

Examples:

(difference)		=> 0	; identity element
(difference 5.3)	=> 5.3	; identity operation
(difference 5.3 2)	=> 3.3	; flonum arithmetic 
(difference 9 2 3)	=> 4	; fixnum arithmetic

MINUSFunction(MINUS n)

Returns the negation of its argument, which can be any kind of number.

Examples:

(minus 1)	=>	-1
(minus -3.6)	=>	3.6

-Function(- i1 i2 ...)

This is the fixnum-only subtraction/negation function. Accepts and returns only fixnums.

Examples:

(-)		=>	0	;identity element
(- 5)		=>	-5	;argument negation
(- 5 3)		=>	2	;subtraction
(- 8 4 3)	=>	1	;repeated subtraction

-$Function(-$ x1 x2 ...)

This is the flonum-only subtraction/negation function. Accepts and returns only flonums.

Examples:

(-$)			=>	0.0	;identity element
(-$ 5.0)		=>	-5.0	;argument negation
(-$ 5.0 3.0)		=>	2.0	;subtraction
(-$ 8.0 4.0 3.0)	=>	1.0	;repeated subtraction

SUB1Function(SUB1 n)

Exactly equivalent to (DIFFERENCE n 1).


1-Function(1- i)

Exactly equivalent to (- i 1).


1-$Function(1-$ x)

Exactly equivalent to (-$ x 1).


TIMESFunction(TIMES n1 n2 ...)

Times returns the product of its arguments. It works for any kind of numbers.


*Function(* i1 i2 ...)

Returns the product of its arguments. The arguments must be fixnums and the result is always a fixnum.

Examples:

(*)		=>	1	;identity element
(* 3)		=>	3	;trivial case
(* 4 5 -6)	=>	-120.

*$Function(*$ x1 x2 ...)

Returns the product of its arguments. The arguments must be flonums and the result is always a flonum.

Examples:

(*$)			=>	1.0	;identity element
(*$ 6.1)		=>	6.1	;trivial case
(*$ 3.0 2.0 4.0)	=>	24.0

EXPTFunction(EXPT n j)

n to the j power. The exponent j may be a bignum if the base n is 0, 1, or -1; otherwise j must be a fixnum. n may be any kind of number.

If j is a flonum, n is converted to floating point and the exponentiation is done using logarithms.


^Function(^ i1 i2)

Fast fixed point exponentiation; like EXPT but for the case where n1 and n2 are both known to be fixnums.


^$Function(^$ x i)

Fast floating point exponentiation; like EXPT but for the case where x is known to be a flonum and i to be fixnum.

To raise a flonum to a floating point power, use (EXPT x y) or (EXP (*$ y (LOG x))).


EXPFunction(EXP k)

Same as e to the k power. k must be a fixnum or a flonum. The value returned will be a flonum.


QUOTIENTFunction(QUOTIENT n1 n2 n3 ...)

Quotient returns its first argument divided by the rest of its arguments. The arguments may any kind of number. (QUOTIENT n1 n2) = n1/n2, (QUOTIENT n1 n2 n3) = (n1/n2)/n3, etc.

Examples:

(quotient)		=> 1.	;identity element
(quotient 5)		=> 5.	;identity operation
(quotient 3 2)		=> 1.	;fixnum division truncates
(quotient 3 2.0)	=> 1.5	;but flonum division does not
(quotient 6.0 1.5  2.0)	=> 2.0

REMAINDERFunction(REMAINDER k1 k2)

Returns k1 mod k2, the remainder of the division of k1 by k2. The sign of the remainder is the same as the sign of the dividend. The arguments must be fixnums or bignums.


SQRTFunction(SQRT n)

Returns a flonum which is the square root of n. n may be any kind of non-negative number.


LOGFunction(LOG n)

Same as ln n, the natural log of n. The input may be any type of positive number (including a bignum) as long as it can be represented as a flonum. If (FLOAT n) would err, then so will (LOG n). The value returned will be a flonum.

Examples:

(log 33.7)			=>	3.51749784
(log 5.0)			=>	1.60943791 
(exp (log 5))			=>	5.0
(log 2.71828184)		=>	1.0
(log 123456789123456789.)	=>	39.3546677
(log (expt 2 150.))		=>	error! ;ARITHMETIC OVERFLOW

DIVOVStatus Option(STATUS DIVOV)

If NIL, the default, create an error when either a division by zero occurs or a floating point overflow occurs in a bignum/flonum conversion. If T, no error occurs but an undefined result may be generated. This switch affects only closed coded calls to generic arithmetic functions (e.g., QUOTIENT). Calls to type specific operations (e.g., //) and calls to generic arithmetic functions which have been open coded due to compiler declarations are also unaffected; they never generate errors, so behave as if this switch were always set to T.


DIVOVSStatus Option(SSTATUS DIVOV flag)

Sets (STATUS DIVOV) to flag, which should be T or NIL.

With respect to the type-specific division functions, here are some points to remember:

* The name of these functions must be typed in as //, since Maclisp uses / as an escape character.

* The results of one-argument division and of division by zero are undefined. That case will not err and its results may frequently appear predictable, but meaningfulness of the results are not guaranteed. Those results are primarily determined by (though not defined by) the behavior of hardware in any given implementation.


//Function(// i1 i2 ...)

This is the fixnum-only division function.

Examples:

(//)	       => 1	;the identity element
(// 17. 3)     => 5	;x/y, integer quotient
(// 17. 3. 2.) => 2	;(x/y)/z, repeated integer quotient

//$Function(//$ x1 x2 ...)

This is the flonum-only division function.

Examples:

(//$)			=>	1.0	;the identity element
(//$ 2.0)		=>	0.5	;the one-arg case is
(//$ 0.0)		=>	0.0	; not well-defined.
(//$ 3.3 2.0)		=>	1.65	;x/y
(//$ 3.3 2.0 2.0)	=>	0.825	;(x/y)/z

\Function(\ i1 i2)

Returns the remainder of the division of i1 by i2, with the sign of i1. Both arguments are supposed to be fixnums. The interpreter currently allows bignum arguments to \ but this should not be relied upon, nor should it be expected to compile correctly with other than fixnum arguments.

Warning: There is a bug in the relation between interpreted and compiled versions of this function such that the pathological case (\ i 0) returns different results interpreted and compiled. This should probably be fixed sometime.


EQUALFunction(EQUAL n1 n2)

There is no function which will compare just two bignums specifically. However, EQUAL, among its other uses, can compare two bignums for numeric equality. In fact, EQUAL will return true for any two numbers as long as they are of the same datatype and have the same sign and magnitude. See the full description of EQUAL elsewhere in this manual.


=Function(= k1 k2)

Compares k1 and k2, returning true if k1 is numerically equal, or false otherwise. k1 and k2 may be either both fixnums or both flonums.


GREATERPFunction(GREATERP n1 n2 ...)

Compares its arguments, which must be numbers, from left to right. If any argument is not greater than the next, returns NIL. But if the arguments are strictly decreasing, the result is T. Arguments may be any kind of number. The arguments need not all be of the same type.

Examples:

(GREATERP 4 3)		=>	T
(GREATERP 1 1)		=>	NIL
(GREATERP 4.0 3.6 -2)	=>	T
(GREATERP 4 3 1 2 0)	=>	NIL

>Function(> k1 k2)

Compares k1 and k2, returning T if k1 is greater than k2 and NIL otherwise. k1 and k2 may be either both fixnums or both flonums.


LESSPFunction(LESSP n1 n2 ...)

Compares its arguments, which must be numbers, from left to right. If any argument is not less than the next, returns NIL. But if the arguments are strictly increasing, the result is T. Arguments may be any kind of number. The arguments need not all be of the same type.

Examples:

(lessp 3 4)		=>	T
(lessp 1 1)		=>	NIL
(lessp -2 3.6 4)	=>	T
(lessp 0 2 1 3 4)	=>	NIL

<Function(< k1 k2)

Compares k1 and k2, returning T if k1 is less than k2 and NIL otherwise. k1 and k2 may be either both fixnums or both flonums.


PLUSPFunction(PLUSP n)

The plusp predicate returns T if its argument is strictly greater than zero, NIL if it is zero or negative. It is an error if the argument is not a number.

Synonym:

(GREATERP n 0)

Examples:

(PLUSP 3.0)	=>	T
(PLUSP -4)	=>	NIL
(PLUSP 0.0)	=>	NIL

ZEROPFunction(ZEROP n)

The zerop predicate returns T if its argument is fixnum zero or flonum zero. (There is no bignum zero.) Otherwise it returns NIL. It is an error if the argument is not a number.

Examples:

(ZEROP 3.0)	=>	NIL
(ZEROP -4)	=>	NIL
(ZEROP 0)	=>	T
(ZEROP 0.0)	=>	T

MINUSPFunction(MINUSP n)

The MINUSP predicate returns T if its argument is a negative number, NIL if it is a non-negative number. It is an error if the argument is not a number.

Synonym:

(LESSP n 0)

Examples:

(MINUSP  3.5)	=>	NIL
(MINUSP -3.5)	=>	T
(MINUSP -0.0)	=>	NIL

ABSFunction(ABS n)

Returns |n|, the absolute value of the number n.

Definition:

(DEFUN ABS (X)
       (COND ((MINUSP X) (MINUS X))
             (T X)))

SIGNPSpecial Form(SIGNP c n)

The SIGNP predicate can be used to test the sign of a number. Returns T if n's sign satisfies the test c, NIL if it does not. n is evaluated but c is not. n may be any kind of number; NIL will be returned if n is not a number. c can be one of the following:

L means x<0 
LE means x≤0 
E means x=0 
N means x≠0 
GE means x≥0 
G means x>0 

Because it is an fsubr and because it is no more efficient than (ZEROP n), (MINUSP n), (NOT (MINUSP n)), etc., its use is discouraged.

Examples:

(SIGNP LE -1)	=>	T	;is -1 non-positive?
(SIGNP N 0)	=>	NIL	;is 0 nonzero?

GCDFunction(GCD k1 k2)

Returns the greatest common divisor of k1 and k2. The arguments must be fixnums or bignums. If either k1 or k2 is 0, the other argument will be returned. The result will be a positive number except when both args are 0, in which case 0 is returned.

Examples:

(GCD 5 3)		=>	1.
(GCD 15. 36.)		=>	3.
(GCD -13424. 80.)	=>	16.
(GCD 0 5)		=>	5.
(GCD -3 0)		=>	3.
(GCD 0 0)		=>	0.

\\Function(\\ i1 i2)

Fixnum-only GCD operator. (See GCD)


ODDPFunction(ODDP j)

Returns T if j is an odd number, otherwise NIL. j must be a fixnum or a bignum. There is no EVENP; use (NOT (ODDP j)) for that.


MAXFunction(MAX n1 n2 ...)

Returns the largest of its arguments, which must be numbers. If any argument is floating point, the result will be floating point; else the result will be of the type of the largest argument.


MINFunction(MIN n1 n2 ...)

Returns the smallest of its arguments, which must be numbers. If any argument is floating point, the result will be floating point; else the result will be of the type of the largest argument.

Trig Functions


ATANFunction(ATAN k1 k2)

Returns the trigonometric arctangent of k1/k2, in radians. k2 may be 0 as long as k1 is not also 0. k1 and k2 may be any kind of numbers. The answer is returned in the range 0 to 2 pi.

Examples:

(ATAN 1.0 3.0)		=> 0.321750563
(ATAN 1.0 -3.0)		=> 2.8198421
(ATAN -1.0 3.0)		=> 5.9614348
(ATAN -1.0 -3.0)	=> 3.46334323
(ATAN 3.0 0.0)		=> 1.57079633
(ATAN 8.0 5.0)		=> 1.01219705

COSFunction(COS k)

Returns the trigonometric cosine of k. k is a fixnum or flonum specification of radians.

Examples:

(COS 1.0)	=> 0.540302314
(COS 3.0)	=> -0.98999251
(COS -3.0)	=> -0.98999251
(COS 5.0)	=> -0.95892429
(COS 8)		=> -0.145500086

SINFunction(SIN k)

Returns the trigonometric sine of k. k is a fixnum or flonum specification of radians.

Examples:

(SIN 1.0)	=> 0.841470994
(SIN 3.0)	=> 0.141120013
(SIN -3.0)	=> -0.141120013
(SIN 5)		=> -0.95892429
(SIN 8)		=> 0.98935825

Random Number Generator


RANDOMFunction(RANDOM [i])

If no argument is given, returns a random fixnum. If i is NIL, restarts the random sequence at its beginning. (RANDOM i), where i is a fixnum, returns a random fixnum between 0 and i-1 inclusive. For info on how to read and set the internal state of the generator, see documentation on (STATUS RANDOM ...) and (SSTATUS RANDOM ...).


RANDOM  

[PDP-10 Only] Returns a list which summarizes the state of the random number generator. No guarantees are made as to its format, except that it may be fed as an argument to (SSTATUS RANDOM ...) to reset the random number generator to its current state.


RANDOMSStatus Option(SSTATUS RANDOM seed)

[PDP-10 Only] Initializes the state of the random number generator to a state described by seed. Seed must be a fixnum or a list which was returned by (STATUS RANDOM).

Controlling Math Operations


ZFUZZValueNIL

[PDP-10 Only] If this variable's value is not NIL, then PLUS and DIFFERENCE perform a special fuzz check on floating point numbers. If x and y are the numbers to be added (possibly after contagious conversion to floating point), then if x + y < y * ZFUZZ then the result is forced to zero.


ZUNDERFLOWValueNIL

If the value of the variable ZUNDERFLOW is not NIL, floating point underflows will return 0.0 as a result. If NIL, floating point underflows will be treated as errors. This flag has no effect on compiled arithmetic operations that were open-coded.

Notes about Declarations

Some functions, such as ABS, have no fixnum-only or flonum-only versions but still do not compile well in the absence of declarations. You can silence compiler warnings about inefficient compilations with

(DECLARE (MUZZLED T))

or, if efficiency matters, you can do appropriate declarations as in:

(DEFUN F1 (X Y) (DECLARE (FIXNUM X Y)) (> X (ABS Y)))
(DEFUN F2 (X Y) (> (FIXNUM-IDENTITY X) (ABS (FIXNUM-IDENTITY Y))))

[Blue Marble]
Climate Change
What issue has higher priority?

The Revised Maclisp Manual (Sunday Morning Edition)
Published Sunday, December 16, 2007 06:17am EST, and updated Sunday, July 6, 2008.
Prev | Index | Next