【问题标题】:Mysterious problem with floating point in LISP - time axis generationLISP中浮点的神秘问题——时间轴生成
【发布时间】:2011-06-03 09:20:55
【问题描述】:

好的,我确实知道浮点的工作原理和方式。但是,每当我处理它时,它都不会停止让我感到困惑。

我尝试做一些时间轴生成功能。这个想法很简单。把 smt 做成这样

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

所以,当你用例如调用它时

(make-time-axis 0 0.1 1.2)

结果是

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

但无论我做什么

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

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

等等

我得到了这些结果

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

谁能告诉我如何得到我想要的东西?

【问题讨论】:

    标签: lisp floating-point


    【解决方案1】:

    如果您知道浮点的工作原理(您已经阅读过What Every Computer Scientist Should Know About Floating Point Arithmetic,对吗?),您应该意识到您得到的正是您所要求的。

    数学数字(无论是整数、有理数、实数、复数等)具有许多有用的属性。例如,x/10 + y/10 = (x+y)/10。这些属性不适用于浮点数。

    根据您的数值结果,在您的实现中,浮点数 0.1 的值似乎略高于数学数 0.1 的值(不能完全表示为浮点数)。多次相加,误差最终会超过打印精度。

    由于您使用的是 Lisp,因此很容易以精确的形式保留数字(例如,有理数 1/10 而不是浮点数 0.1)并在最后一分钟进行转换。

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

    【讨论】:

      猜你喜欢
      • 2012-08-27
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多