【发布时间】:2020-12-29 20:51:10
【问题描述】:
为了对涉及大量浮动算术的系统进行一些测试,我定义了浮动算术误差的偏差范围,因此如果两个浮点数之间的差异在偏差范围内,则它们在数学上被认为是相等的:
;;; Floating Error Agnostic =
;;; F2 is = to F1 within the deviation range +-DEV
(defparameter *flerag-devi* .0005
"Allowed deviation range, within which two floats
should be considered as mathematically equal.")
(defun flerag= (f1 f2 &optional (devi *flerag-devi*))
""
(<= (abs (- f1 f2)) devi))
现在,当我通过将浮点数与 添加 的随机分数进行比较来测试函数时,响应是(至少就我对函数的测试而言)是积极的,例如:
(loop repeat 100000000
with f = 1.0
always (flerag= f (+ f (random *flerag-devi*)))) ;T
当我从原始浮点数中减去一个随机分数时也是这种情况,例如:
(loop repeat 100000000
with f = 19.0
always (flerag= f (- f (random *flerag-devi*)))) ;T
(loop repeat 100000000
with f = 3
always (flerag= f (- f (random *flerag-devi*)))) ;T
但是,当我将原始浮点数设置为 1.0(或 1)时:
(loop repeat 100000000
with f = 1.0
always (flerag= f (- f (random *flerag-devi*)))) ;NIL
它总是返回 NIL,这在我看来更奇怪,因为它在评估后立即返回 NIL(在其他情况下,计算 100000000 次需要几秒钟)。到目前为止,这仅发生在 f = 1.0 上,而没有其他数字,无论对它们进行加法或减法。任何人都可以在他/她的 Lisp 上重现这种行为吗?任何解释和帮助将不胜感激。
更新
f = 1.0 的情况也与其他情况一样,当我使用双浮点 1 时,即 1d0 或这样做:
(setf *read-default-float-format* 'double-float)
【问题讨论】:
-
(1) 你说的是随机“分数”,但这有点令人困惑 (2) 关于执行时间“总是”会在第一个 NIL 早期终止循环,而对于结果 T 所有测试都必须通过
-
1) 对于随机分数,我只是指 (random flerag-devi) 2) 我知道这一点,我只是好奇为什么提前终止会发生在 f = 1.0(在 `*read-default-float-format* = single 下)而不是其他实数。
标签: common-lisp