Common Lisp: Numbers
source link: https://www.tuicool.com/articles/m2yaEjz
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Common Lisp has a rich set of numerical types, including integer, rational, floating point, and complex.
Some sources:

Numbers
in Common Lisp the Language, 2nd Edition 
Numbers, Characters and Strings
in Practical Common Lisp
Introduction
Integer types
Common Lisp provides a true integer type, called bignum
, limited only by the total
memory available (not the machine word size). For example this would
overflow a 64 bit integer by some way:
* (expt 2 200) 1606938044258990275541962092341162602522202993782792835301376
For efficiency, integers can be limited to a fixed number of bits,
called a fixnum
type. The range of integers which can be represented
is given by:
* mostpositivefixnum 4611686018427387903 * mostnegativefixnum 4611686018427387904
Functions which operate on or evaluate to integers include:

isqrt
, which returns the greatest integer less than or equal to the exact positive square root of natural.
* (isqrt 10) 3 * (isqrt 4) 2
Rational types
Rational numbers of type
ratio
consist of two bignum
s, the
numerator and denominator. Both can therefore be arbitrarily large:
* (/ (1+ (expt 2 100)) (expt 2 100)) 1267650600228229401496703205377/1267650600228229401496703205376
It is a subtype of the
rational
class, along with
integer
.
Floating point types
See Common Lisp the Language, 2nd Edition, section 2.1.3 .
Floating point types attempt to represent the continuous real numbers using a finite number of bits. This means that many real numbers cannot be represented, but are approximated. This can lead to some nasty surprises, particularly when converting between base10 and the base2 internal representation. If you are working with floating point numbers then reading What Every Computer Scientist Should Know About FloatingPoint Arithmetic is highly recommended.
The Common Lisp standard allows for several floating point types. In
order of increasing precision these are: shortfloat
, singlefloat
, doublefloat
, and longfloat
. Their precisions are
implementation dependent, and it is possible for an implementation to
have only one floating point precision for all types.
The constants
shortfloatepsilon
, singlefloatepsilon
, doublefloatepsilon
and longfloatepsilon
give
a measure of the precision of the floating point types, and are
implementation dependent.
Floating point literals
When reading floating point numbers, the default type is set by the special
variable
*readdefaultfloatformat*
. By
default this is SINGLEFLOAT
, so if you want to ensure that a number is read
as double precision then put a d0
suffix at the end
* (typeof 1.24) SINGLEFLOAT * (typeof 1.24d0) DOUBLEFLOAT
Other suffixes are s
(short), f
(single float), d
(double
float), l
(long float) and e
(default; usually single float).
The default type can be changed, but note that this may break packages
which assume singlefloat
type.
* (setq *readdefaultfloatformat* 'doublefloat) * (typeof 1.24) DOUBLEFLOAT
Note that unlike in some languages, appending a single decimal point to the end of a number does not make it a float:
* (typeof 10.) (INTEGER 0 4611686018427387903) * (typeof 10.0) SINGLEFLOAT
Floating point errors
If the result of a floating point calculation is too large then a floating point overflow occurs. By default in SBCL (and other implementations) this results in an error condition:
* (exp 1000) ; Evaluation aborted on #<FLOATINGPOINTOVERFLOW {10041720B3}>.
The error can be caught and handled, or this behaviour can be
changed, to return +infinity
. In SBCL this is:
* (sbint:setfloatingpointmodes :traps '(:INVALID :DIVIDEBYZERO)) * (exp 1000) #.SBEXT:SINGLEFLOATPOSITIVEINFINITY * (/ 1 (exp 1000)) 0.0
The calculation now silently continues, without an error condition.
A similar functionality to disable floating overflow errors exists in CCL :
* (setfpumode :overflow nil)
In SBCL the floating point modes can be inspected:
* (sbint:getfloatingpointmodes) (:TRAPS (:OVERFLOW :INVALID :DIVIDEBYZERO) :ROUNDINGMODE :NEAREST :CURRENTEXCEPTIONS NIL :ACCRUEDEXCEPTIONS NIL :FASTMODE NIL)
Arbitrary precision
For arbitrary high precision calculations there is the computablereals library on QuickLisp:
* (ql:quickload :computablereals) * (usepackage :computablereals) * (sqrtr 2) +1.41421356237309504880... * (sinr (/r +pir+ 2)) +1.00000000000000000000...
The precision to print is set by *PRINTPREC*
, by default 20
* (setq *PRINTPREC* 50) * (sqrtr 2) +1.41421356237309504880168872420969807856967187537695...
Complex types
There are 5 types of complex number: The real and imaginary parts must be of the same type, and can be rational, or one of the floating point types (short, single, double or long).
Complex values can be created using the #C
reader macro or the function
complex
. The reader macro does not allow the use of expressions
as real and imaginary parts:
* #C(1 1) #C(1 1) * #C((+ 1 2) 5) ; Evaluation aborted on #<TYPEERROR expectedtype: REAL datum: (+ 1 2)>. * (complex (+ 1 2) 5) #C(3 5)
If constructed with mixed types then the higher precision type will be used for both parts.
* (typeof #C(1 1)) (COMPLEX (INTEGER 1 1)) * (typeof #C(1.0 1)) (COMPLEX (SINGLEFLOAT 1.0 1.0)) * (typeof #C(1.0 1d0)) (COMPLEX (DOUBLEFLOAT 1.0d0 1.0d0))
The real and imaginary parts of a complex number can be extracted using
realpart
and imagpart
:
* (realpart #C(7 9)) 7 * (imagpart #C(4.2 9.5)) 9.5
Complex arithmetic
Common Lisp’s mathematical functions generally handle complex numbers, and return complex numbers when this is the true result. For example:
* (sqrt 1) #C(0.0 1.0) * (exp #C(0.0 0.5)) #C(0.87758255 0.47942555) * (sin #C(1.0 1.0)) #C(1.2984576 0.63496387)
Reading numbers from strings
The
parseinteger
function reads an integer from a string.
The parsefloat library provides a parser which cannot evaluate arbitrary expressions, so should be safer to use on untrusted input:
* (ql:quickload :parsefloat) * (usepackage :parsefloat) * (parsefloat "23.4e2" :type 'doublefloat) 2340.0d0 6
See thestrings section on converting between strings and numbers.
Converting numbers
Most numerical functions automatically convert types as needed.
The coerce
function converts objects from one type to another,
including numeric types.
See Common Lisp the Language, 2nd Edition, section 12.6 .
Convert float to rational
The
rational
and rationalize
functions
convert
a real numeric argument into a rational. rational
assumes that floating
point arguments are exact; rationalize
expoits the fact that floating point
numbers are only exact to their precision, so can often find a simpler
rational number.
Convert rational to integer
If the result of a calculation is a rational number where the numerator is a multiple of the denominator, then it is automatically converted to an integer:
* (typeof (* 1/2 4)) (INTEGER 0 4611686018427387903)
Rounding floatingpoint and rational numbers
The
ceiling
, floor
, round
and truncate
functions
convert floating point or rational numbers to integers. The difference
between the result and the input is returned as the second value, so that the
input is the sum of the two outputs.
* (ceiling 1.42) 2 0.58000004 * (floor 1.42) 1 0.41999996 * (round 1.42) 1 0.41999996 * (truncate 1.42) 1 0.41999996
There is a difference between floor
and truncate
for negative
numbers:
* (truncate 1.42) 1 0.41999996 * (floor 1.42) 2 0.58000004 * (ceiling 1.42) 1 0.41999996
Similar functions fceiling
, ffloor
, fround
and ftruncate
return the result as floating point, of the same type as their
argument:
* (ftruncate 1.3) 1.0 0.29999995 * (typeof (ftruncate 1.3)) SINGLEFLOAT * (typeof (ftruncate 1.3d0)) DOUBLEFLOAT
Comparing numbers
See Common Lisp the Language, 2nd Edition, Section 12.3 .
The =
predicate returns T
if all arguments are numerically equal.
Note that comparison of floating point numbers includes some margin
for error, due to the fact that they cannot represent all real
numbers and accumulate errors.
The constant
singlefloatepsilon
is the smallest
number which will cause an =
comparison to fail, if it is added to 1.0:
* (= (+ 1s0 5e8) 1s0) T * (= (+ 1s0 6e8) 1s0) NIL
Note that this does not mean that a singlefloat
is always precise
to within 6e8
:
* (= (+ 10s0 4e7) 10s0) T * (= (+ 10s0 5e7) 10s0) NIL
Instead this means that singlefloat
is precise to approximately
seven digits. If a sequence of calculations are performed, then error
can accumulate and a larger error margin may be needed. In this case
the absolute difference can be compared:
* (< (abs ( (+ 10s0 5e7) 10s0)) 1s6) T
When comparing numbers with =
mixed types are allowed. To test both
numerical value and type use eql
:
* (= 3 3.0) T * (eql 3 3.0) NIL
Operating on a series of numbers
Many Common Lisp functions operate on sequences, which can be either lists or vectors (1D arrays). See the section onmapping.
Operations on multidimensional arrays are discussed inthis section.
Libraries are available for defining and operating on lazy sequences, including “infinite” sequences of numbers. For example
 Clazy which is on QuickLisp.
 folio2 on QuickLisp. Includes an interface to the
 Series package for efficient sequences.
 lazyseq .
Working with Roman numerals
The format
function can convert numbers to roman numerals with the ~@r
directive:
* (format nil "~@r" 42) "XLII"
There is a gist by tormaroe for reading roman numerals.
Generating random numbers
The
random
function generates either integer or floating point
random numbers, depending on the type of its argument.
* (random 10) 7 * (typeof (random 10)) (INTEGER 0 4611686018427387903) * (typeof (random 10.0)) SINGLEFLOAT * (typeof (random 10d0)) DOUBLEFLOAT
In SBCL a Mersenne Twister pseudorandom number generator is used. See section 7.13 of the SBCL manual for details.
The random seed is stored in
*randomstate*
whose internal
representation is implementation dependent. The function
makerandomstate
can be used to make new random
states, or copy existing states.
To use the same set of random numbers multiple times, (makerandomstate nil)
makes a copy of the current *randomstate*
:
* (dotimes (i 3) (let ((*randomstate* (makerandomstate nil))) (format t "~a~%" (loop for i from 0 below 10 collecting (random 10))))) (8 3 9 2 1 8 0 0 4 1) (8 3 9 2 1 8 0 0 4 1) (8 3 9 2 1 8 0 0 4 1)
This generates 10 random numbers in a loop, but each time the sequence
is the same because the *randomstate*
special variable is dynamically
bound to a copy of its state before the let
form.
Other resources:
 The randomstate package is available on QuickLisp, and provides a number of portable random number generators.
Bitwise Operation
Common Lisp also provides many functions to perform bitwise arithmetic operations. Some commonly used ones are listed below, together with their C/C++ equivalence.
Common Lisp C/C++ Description(logand a b c)
a & b & c
Bitwise AND of multiple operands
(logior a b c)
a  b  c
Bitwise OR of multiple arguments
(lognot a)
~a
Bitwise NOT of single operand
(logxor a b c)
a ^ b ^ c
Bitwise exclusive or (XOR) or multiple operands
(ash a 3)
a << 3
Bitwise left shift
(ash a 3)
a >> 3
Bitwise right shift
Negative numbers are treated as two’scomplements. If you have forgotten this, please refer to the Wiki page .
For example:
* (logior 1 2 4 8) 15 ;; Explanation: ;; 0001 ;; 0010 ;; 0100 ;;  1000 ;;  ;; 1111 * (logand 2 3 4) 0 ;; Explanation: ;; 0010 (2) ;; 1101 (two's complement of 3) ;; & 0100 (4) ;;  ;; 0000 * (logxor 1 3 7 15) 10 ;; Explanation: ;; 0001 ;; 0011 ;; 0111 ;; ^ 1111 ;;  ;; 1010 * (lognot 1) 0 ;; Explanation: ;; 11 > 00 * (lognot 3) 2 ;; 101 > 010 * (ash 3 2) 12 ;; Explanation: ;; 11 > 1100 * (ash 5 2) 2 ;; Explanation ;; 11011 > 110
Please see the CLHS page for a more detailed explanation or other bitwise functions.
Page source: numbers.md
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK