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