我对下面的LISP表达式有问题。对浮点数字求和时存在浮点精度错误。
CL-USER> (+ -380 -158.27 -35.52)
Actual: -573.79004
Expected: -573.79000
请建议我如何在LISP中实现预期结果(我正在使用Lispworks)。
浮点数不一定精确。通常,一个实现具有单浮点和双浮点。也可能有长短浮动。
单浮子
CL-USER 7 > (+ -380 -158.27 -35.52)
-573.79004
现在有双浮动:
CL-USER 8 > (+ -380 -158.27d0 -35.52d0)
-573.79D0
因此,LispWorks有两种不同的浮点类型(短浮点可能是第三种,取决于32位或64位架构):
CL-USER 9 > (describe 35.52)
35.52 is a SINGLE-FLOAT
CL-USER 10 > (describe 35.52d0)
35.52D0 is a DOUBLE-FLOAT
另请参见:*read-default-float-format*
。
浮动不准确
浮点表示具有特定精度的数学实数的子集,它们是而不是精确的数字。舍入误差是不可避免的。
ANSI Common Lisp标准提供了4个(!)级别的浮点精度:短、单、双、长(所有实现至少提供2个)。两者都不准确,但ORACLE可能使用double
,所以如果您坚持使用doubles,应该没问题。
理论
请阅读每一位计算机科学家应该知道的关于浮点运算的知识。
如果想要精确的数字,请使用整数和比率
如果您想进行精确的计算,您应该使用integer
s(例如,将货币表示为美分,而不是美元)或ratio
s。