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 almost 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 systems, notably 32-bit x86.
On some old computer systems, Emacs may not use IEEE floating-point. We know of one such system on which Emacs runs correctly, but does not follow IEEE-754: the VAX running NetBSD using GCC 10.4.0, where the VAX ‘D_Floating’ format is used instead. IBM System/370-derived mainframes and their XL/C compiler are also capable of utilizing a hexadecimal floating point format, but Emacs has not yet been built in such a configuration.
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 a decimal point in a floating-point number that does not have an exponent; ‘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.
NaNs are not available on systems which do not use IEEE floating-point arithmetic; if the read syntax for a NaN is used on a VAX, for example, the reader signals an error.
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:
‘1.0e+INF’ and ‘-1.0e+INF’
‘0.0e+NaN’ and ‘-0.0e+NaN’
The following functions are specialized for handling floating-point numbers:
isnan
x ¶This predicate returns t
if its floating-point argument is a NaN,
nil
otherwise.
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.
ldexp
s e ¶Given a numeric significand s and an integer exponent e, this function returns the floating point number s * 2**e.
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.
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