Clojure:减法中的舍入不一致

时间:2013-05-28 20:31:45

标签: clojure rounding numerical-stability

我正在编写一段代码,其中数字相等是几个逻辑条件中的重要因素。 Clojure正在做一些我不太了解的事情。例如:

user=> (- 5 4.9)
0.09999999999999964
user=> (- 5 4.8)
0.20000000000000018
user=> (- 5 2.9)
2.1
user=> (- 5 2.7)
2.3
user=> (- 5 2.8)
2.2
user=> (- 9 6.9)
2.0999999999999996 
user=> (- 9 2.9)
6.1

似乎在某些情况下,Clojure数字会将减法理解为0.1,而在其他情况下则不然。这里发生了什么?

2 个答案:

答案 0 :(得分:6)

默认情况下,这些结果以小数表示,并带有固有的舍入误差。您可以通过后缀字母M切换到使用BigDecimals:

user=> (- 5M 4.9M)
0.1M
user=> (- 5M 4.8M)
0.2M
user=> (- 9M 6.9M)
2.1M
user=> (- 9M 2.9M)
6.1M

要对小数变量执行相同操作,请使用bigdec格式:

user=> (def k 4.9)
#'user/k
user=> (- 5M k)
0.09999999999999964
user=> (- 5M (bigdec k))
0.1M

答案 1 :(得分:4)

在所讨论的数字文字中添加一些M来解决这些症状,但没有改善David对浮点数学基本原理的理解。请参阅经典What Every Computer Scientist Should Know About Floating-Point Arithmetic,或关于浮点不精确性的众多问题中的任何一个。这是我可以轻易找到的两个例子;我已经看过Clojure中至少有三个,但很难通过搜索找到它们。