(= 1/5 0.2)是假的?

Roy*_*ado 3 lisp scheme common-lisp

这是常见的lisp(clisp和sbcl)和scheme(guile).虽然这些都是真的:

(= 1/2 0.5)
(= 1/4 0.25)
Run Code Online (Sandbox Code Playgroud)

结果证明这是假的:

(= 1/5 0.2)
Run Code Online (Sandbox Code Playgroud)

我检查了hyperspec,它说"="应该检查数学等价,尽管参数的类型.到底他妈发生了什么?

hug*_*omg 21

问题是0.2真的等于1/5.浮点数不能正确表示0.2,因此文字0.2实际上舍入为最接近的可表示浮点数(0.200000001或类似的值).发生此舍入后,计算机无法知道您的号码最初是0.2而不是另一个附近的不可表示的号码(例如0.20000000002).

至于1/2和1/4的原因是因为浮点是基数2编码,并且可以准确地表示2的幂.

  • 我的观点是,它评估为"13421773/67108864".所以它不等于1/5.这并不奇怪,因为"0.2"实际上代表"0.2"的浮点表示,它不是0.2. (3认同)
  • 有趣的是,在千里马:`:lisp(= 1/5 0.2)`计算为`T`,但`:lisp(理性0.2)`是`3602879701896397/18014398509481984`. (2认同)