开发者

Mysterious problem with floating point in LISP - time axis generation

Ok, I do know what and how works floating point. But, It doesn't stop to puzzle me whenever I deal with it.

I try to do some time axis generation function. The idea is simple. To make smt like this

(defun make-time-axis (start step stop)
  ...)

So, when you call it with e.g.

(make-time-axis 0 0.1 1.2)

result will be

0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 1.1 

But whenever I do whatever

(loop for i from 0.0 below 1.2 by 0.1 collect i)

or

(defun make-time-axis (last step stop)
  (cond  ((< last stop ) (cons last (make-time-axis (+ last step) step stop )))
     (t nil)))

etc.

I getting these results

(0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.70000005 0.8000001 0.9000001 1.0000001 1.1000001)

Can anybode give me some clue how to 开发者_JAVA技巧get What I want?


If you know how floating point works (you have read What Every Computer Scientist Should Know About Floating Point Arithmetic, right?), you should realize that you got exactly what you asked for.

Mathematical numbers (be they integers, rationals, reals, complex, whatever) have many useful properties. For example, x/10 + y/10 = (x+y)/10. These properties don't hold for floating point numbers.

Given your numerical results, it seems that in your implementation, the value of the floating-point number 0.1 is slightly above the value of the mathematical number 0.1 (which isn't exactly representable as floating point). When you add it up several times, the error eventually rises above the printing precision.

Since you're using Lisp, it's easy to retain numbers in exact form (e.g. the rational 1/10 instead of the float 0.1) and convert them at the last minute.

(loop for i from 0 below 12/10 by 1/10 collect (float i))
(mapcar #'float (make-time-axis 0 1/10 12/10))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜