The Revised Maclisp Manual | Page A-9 | ||||||
|
|
Numbers | Concept | Numeric 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 |
FIX | Function | (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
IFIX | Function | (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.
FLOAT | Function | (FLOAT n) |
Numerical Type Predicates |
NUMBERP | Function | (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
FIXNUMP | Function | (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
BIGP | Function | (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
FIXP | Function | (FIXP q) |
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
FLOATP | Function | (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
PLUS | Function | (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
ADD1 | Function | (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).
DIFFERENCE | Function | (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
MINUS | Function | (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
SUB1 | Function | (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).
TIMES | Function | (TIMES n1 n2 ...) |
* | 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
EXPT | Function | (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) |
EXP | Function | (EXP k) |
QUOTIENT | Function | (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
REMAINDER | Function | (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.
SQRT | Function | (SQRT n) |
LOG | Function | (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
DIVOV | Status 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.
DIVOV | SStatus Option | (SSTATUS DIVOV flag) |
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.
EQUAL | Function | (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.
GREATERP | Function | (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) |
LESSP | Function | (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) |
PLUSP | Function | (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
ZEROP | Function | (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
MINUSP | Function | (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
ABS | Function | (ABS n) |
Returns |n|, the absolute value of the number n.
Definition:
(DEFUN ABS (X) (COND ((MINUSP X) (MINUS X)) (T X)))
SIGNP | Special 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?
GCD | Function | (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) |
ODDP | Function | (ODDP j) |
MAX | Function | (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.
MIN | Function | (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 |
ATAN | Function | (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
COS | Function | (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
SIN | Function | (SIN k) |
Random Number Generator |
RANDOM | Function | (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 | ||
RANDOM | SStatus Option | (SSTATUS RANDOM seed) |
Controlling Math Operations |
ZFUZZ | Value | NIL |
ZUNDERFLOW | Value | NIL |
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))))
|
The Revised Maclisp Manual (Sunday Morning Edition) Published Sunday, December 16, 2007 06:17am EST, and updated Sunday, July 6, 2008. |
|