common-lisp - Common Lisp 中分数的相等性检查

标签 common-lisp precision floating-accuracy fractions

所以我正在学习 Lisp 做分数,这很棒。但是为什么这个相等性检查返回 NIL:

* (= 0.2 1/5)          

NIL

...如果转换为 float 则返回 True第一的:
* (= 0.2 (float 1/5))

T

我试过 SBCLCLISP .

实现是否不完整,或者这种行为背后是否有特殊原因或逻辑?

最佳答案

Common Lisp 中的比率

请注意,分数(在 Common Lisp 中它本身不是数字类型)在 Lisp 中被转换为有理数。 rational , ratiointeger (和其他)是 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.51/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组合不相交的子类型 ratiointeger .因此(rational 1.0)可以是整数,而不是比率。

关于common-lisp - Common Lisp 中分数的相等性检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32889606/

相关文章:

lisp - 如何通过知道其在 lisp 中的位置来查找列表元素?

macos - 由于 sdl_delay,lispbuilder-sdl 在 osx 上不工作

objective-c - 为什么 C 语言中的 Float error 不同?

ios - 什么时候使用 NSDecimal、NSDecimalNumber 而不是 double 更好?

math - float 学坏了吗?

lisp - 比较 lisp 中的字符串

lisp - 避免 Clozure lisp 中的回声(菜鸟)

c++ - acos(double) 在 x64 和 x32 Visual Studio 上给出不同的结果

c++ -/fp :fast 的奇怪结果

python - 对于给定的精度,float32 将给出与 float64 相同结果的最大值是多少?