为什么clojure clojure.lang.Ratio 3/2 not=1.5

why clojure clojure.lang.Ratio 3/2 not=1.5

我迷失在 clojure 比率中。我无法理解。为什么等式和不等式测试会这样?

(= 3/2 1.5)
;; false
(>= 3/2 1.5)
;; true
(> 3/2 1.5)
;;false
(not= 3/2 1.5)
;; true

使用 == 进行数值比较,无论类型如何,您想知道两个数字是否表示相同的数字:

user> (= 3/2 1.5)
false
user> (== 3/2 1.5)
true

但请记住 == 仅适用于数字 并且如果给定的不是数字则抛出。

user> (== :1 :1)
ClassCastException clojure.lang.Keyword cannot be cast to java.lang.Number  clojure.lang.Numbers.equiv (Numbers.java:206)

Clojure 努力让您远离浮点数,因为它们容易出现舍入错误:

user=> (+ 0.1 0.2)
0.30000000000000004
user=> 

所以比较失败的真正原因是没有准确的方法在内部表示 1.5,并且 Clojure 解析器消耗“1.5”信息的那一刻可能会丢失

通过使用分数,不会丢失信息,因此可以将分数形式 3/2 自由传递给其他函数,而不必担心失控的舍入错误as was the case with the infamous Patriot missile bug.

简单的说,在Clojure里ratio就是一个类型。它不会尝试将其转换为 double 或 float 或任何类似的东西。这样您就可以保留数字实际代表的内容而不会丢失任何精度。

在 YouTube 上查看 Rich Hickey 的演讲 "Clojure for Java Programmers",他解释得更好。