3.2 Floating-Point Basics
Floating-point numbers are useful for representing numbers that are not integral. The range of floating-point numbers is the same as the range of the C data type double
on the machine you are using. On all computers supported by Emacs, this is IEEE binary64 floating point format, which is standardized by IEEE Std 754-2019 and is discussed further in David Goldbergβs paper βWhat Every Computer Scientist Should Know About Floating-Point Arithmetic". On modern platforms, floating-point operations follow the IEEE-754 standard closely; however, results are not always rounded correctly on some obsolescent platforms, notably 32-bit x86.
The read syntax for floating-point numbers requires either a decimal point, an exponent, or both. Optional signs (β+
β or β-
β) precede the number and its exponent. For example, β1500.0
β, β+15e2
β, β15.0e+2
β, β+1500000e-3
β, and β.15e4
β are five ways of writing a floating-point number whose value is 1500. They are all equivalent. Like Common Lisp, Emacs Lisp requires at least one digit after any decimal point in a floating-point number; β1500.
β is an integer, not a floating-point number.
Emacs Lisp treats -0.0
as numerically equal to ordinary zero with respect to numeric comparisons like =
. This follows the IEEE floating-point standard, which says -0.0
and 0.0
are numerically equal even though other operations can distinguish them.
The IEEE floating-point standard supports positive infinity and negative infinity as floating-point values. It also provides for a class of values called NaN, or βnot a number"; numerical functions return such values in cases where there is no correct answer. For example, (/ 0.0 0.0)
returns a NaN. A NaN is never numerically equal to any value, not even to itself. NaNs carry a sign and a significand, and non-numeric functions treat two NaNs as equal when their signs and significands agree. Significands of NaNs are machine-dependent, as are the digits in their string representation.
When NaNs and signed zeros are involved, non-numeric functions like eql
, equal
, sxhash-eql
, sxhash-equal
and gethash
determine whether values are indistinguishable, not whether they are numerically equal. For example, when x
and y
are the same NaN, (equal x y)
returns t
whereas (= x y)
uses numeric comparison and returns nil
; conversely, (equal 0.0 -0.0)
returns nil
whereas (= 0.0 -0.0)
returns t
.
Here are read syntaxes for these special floating-point values:
infinityβ
β1.0e+INF
β and β-1.0e+INF
β
not-a-numberβ
β0.0e+NaN
β and β-0.0e+NaN
β
The following functions are specialized for handling floating-point numbers:
function
isnan xβ
This predicate returns t
if its floating-point argument is a NaN, nil
otherwise.
function
frexp xβ
This function returns a cons cell (s . e)
, where s
and e
are respectively the significand and exponent of the floating-point number x
.
If x
is finite, then s
is a floating-point number between 0.5 (inclusive) and 1.0 (exclusive), e
is an integer, and x
= s
* 2**e
. If x
is zero or infinity, then s
is the same as x
. If x
is a NaN, then s
is also a NaN. If x
is zero, then e
is 0.
function
ldexp s eβ
Given a numeric significand s
and an integer exponent e
, this function returns the floating point number s
* 2**e
.
function
copysign x1 x2β
This function copies the sign of x2
to the value of x1
, and returns the result. x1
and x2
must be floating point.
function
logb xβ
This function returns the binary exponent of x
. More precisely, if x
is finite and nonzero, the value is the logarithm base 2 of |x|, rounded down to an integer. If x
is zero or infinite, the value is infinity; if x
is a NaN, the value is a NaN.
(logb 10)
β 3
(logb 10.0e20)
β 69
(logb 0)
β -1.0e+INF