short-float-epsilon, short-float-negative-epsilon, single-float-epsilon, single-float-negative-epsilon, double-float-epsilon, double-float-negative-epsilon, long-float-epsilon, long-float-negative-epsilon
short-float-epsilon, short-float-negative-epsilon, single-float-epsilon, single-float-negative-epsilon, double-float-epsilon, double-float-negative-epsilon, long-float-epsilon, long-float-negative-epsilon Con stant Variable
Constant Value:
implementation-dependent.
Description:
The value of each of the constants short-float-epsilon, single-float-epsilon, double-float-epsilon, and long-float-epsilon is the smallest positive float ε of the given format, such that the following expression is true when evaluated:
(not (= (float 1 ε) (+ (float 1 ε) ε)))
The value of each of the constants short-float-negative-epsilon, single-float-negative-epsilon, double-float-negative-epsilon, and long-float-negative-epsilon is the smallest positive float ε of the given format, such that the following expression is true when evaluated:
(not (= (float 1 ε) (- (float 1 ε) ε)))
Expanded Reference: short-float-epsilon, short-float-negative-epsilon, single-float-epsilon, single-float-negative-epsilon, double-float-epsilon, double-float-negative-epsilon, long-float-epsilon, long-float-negative-epsilon
Examining Epsilon Values
Each epsilon constant is the smallest positive float such that (not (= 1.0 (+ 1.0 epsilon))) is true for that float type. The negative epsilon variants work for subtraction.
single-float-epsilon
=> 5.960465e-8
single-float-negative-epsilon
=> 2.9802326e-8
double-float-epsilon
=> 1.1102230246251568d-16
double-float-negative-epsilon
=> 5.551115123125784d-17
Verifying the Definition
The epsilon is the smallest value where adding it to 1.0 produces a distinguishable result.
;; Epsilon is distinguishable from zero when added to 1.0
(/= 1.0 (+ 1.0 single-float-epsilon))
=> T
(= 1.0 (+ 1.0 (/ single-float-epsilon 2.0)))
=> T
(/= 1.0d0 (+ 1.0d0 double-float-epsilon))
=> T
(= 1.0d0 (+ 1.0d0 (/ double-float-epsilon 2.0d0)))
=> T
Practical Use: Approximate Float Comparison
Epsilon values are essential for writing correct floating-point comparison functions, since exact equality with = is unreliable for computed floats.
(defun float-nearly-equal (a b &optional (tolerance single-float-epsilon))
"Compare two floats for approximate equality."
(let ((diff (abs (- a b)))
(scale (max (abs a) (abs b) 1.0)))
(<= diff (* scale tolerance))))
(float-nearly-equal 1.0 (+ 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1))
;; => impl-dependent
(= 1.0 (+ 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1))
=> NIL
Relationship Between Float Types
Double-float epsilon is much smaller than single-float epsilon, reflecting greater precision. On many implementations, short-float and single-float share the same epsilon, as do double-float and long-float.
;; Comparing precision across types
(< double-float-epsilon single-float-epsilon)
=> T
;; On many implementations:
;; short-float-epsilon = single-float-epsilon
;; long-float-epsilon = double-float-epsilon