问题
I am having problem with the LISP expression below. There is floating precision error while doing sum for floating point numbers.
CL-USER> (+ -380 -158.27 -35.52)
Actual: -573.79004
Expected: -573.79000
Please suggest me how can I achieve the expected result in LISP (I am using Lispworks).
回答1:
Floats are not exact
Floats represent a subset of mathematical reals with certain precision, they are not exact numbers. Round off errors are inevitable.
The ANSI Common Lisp standard provides for 4(!) levels of float precision: short, single, double, long (all implementations provide at least 2). Neither is exact, but ORACLE is probably using double
, so if you stick with doubles, you should be fine.
Theory
Please read What Every Computer Scientist Should Know About Floating-Point Arithmetic.
Use integers and ratios if you want exact numbers
If you want to do exact computations, you should be using integers (e.g., representing currency as a number of cents, not dollars) or ratios.
回答2:
Floating point numbers are not necessarily exact. Typically an implementation has single and double floats. There might be also short and long floats.
Single float
CL-USER 7 > (+ -380 -158.27 -35.52)
-573.79004
Now with double floats:
CL-USER 8 > (+ -380 -158.27d0 -35.52d0)
-573.79D0
LispWorks thus has two different float types (possibly short-float is a third, depending of 32bit or 64bit architecture):
CL-USER 9 > (describe 35.52)
35.52 is a SINGLE-FLOAT
CL-USER 10 > (describe 35.52d0)
35.52D0 is a DOUBLE-FLOAT
See also: *read-default-float-format*.
来源:https://stackoverflow.com/questions/20490115/floating-point-precision-error