所以我正在学习 Lisp 做分数,这很棒。但是为什么这个相等性检查返回 NIL:
* (= 0.2 1/5)
NIL
...如果转换为
float
则返回 True第一的:* (= 0.2 (float 1/5))
T
我试过
SBCL
和 CLISP
.实现是否不完整,或者这种行为背后是否有特殊原因或逻辑?
最佳答案
Common Lisp 中的比率
请注意,分数(在 Common Lisp 中它本身不是数字类型)在 Lisp 中被转换为有理数。 rational
, ratio
和 integer
(和其他)是 Common Lisp 中的实际数字类型。如果您输入一个分数,它会被归一化为有理数(整数或比率数)。
CL-USER 16 > 3/9
1/3
CL-USER 17 > 9/9
1
CL-USER 18 > 6/9
2/3
数值比较
比较 float 和 ratio 时,将 float 值转换为有理数,然后进行精确比较。见:CLHS, Rule of Float and Rational Contagion .
比率不会转换为浮点数,而是将浮点数转换为有理数。
出现问题是因为某些浮点数未转换为您期望的比率。潜在的问题是浮点数不一定有精确的表示。将非精确数转换为精确有理数不是给出天真的预期结果的必要条件。
不幸的是
0.2
的转换有理数不一定是1/5
, 但是这个:CL-USER 7 > (rational 0.2)
13421773/67108864
但是
0.5
是 1/2
.CL-USER 8 > (rational 0.5)
1/2
这就是您的示例中发生的情况:
CL-USER 9 > (= 1/2 (rational 0.5))
T
CL-USER 10 > (= 1/5 (rational 0.2))
NIL
所以它不是
CL-USER 14 > (= 0.2 (float 1/5))
T
但:
CL-USER 15 > (= (rational 0.2) 1/5)
NIL
注意类型
rational
组合不相交的子类型 ratio
和 integer
.因此(rational 1.0)
可以是整数,而不是比率。
关于common-lisp - Common Lisp 中分数的相等性检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32889606/