2015-02-02 8 views
10

Ben clojure oranında kayboldum. Anlayamıyorum. Eşitlik ve eşitsizlik testleri neden böyle davranıyor?neden clojure clojure.lang.Ratio 3/2 not 0 1.5

(= 3/2 1.5) 
;; false 
(>= 3/2 1.5) 
;; true 
(> 3/2 1.5) 
;;false 
(not= 3/2 1.5) 
;; true 
Eğer iki sayı türlerinden bakılmaksızın aynı sayıda temsil bilmek istiyorum sayısal karşılaştırmalar için
+0

bu soru bir kopyası değildir: http://stackoverflow.com/questions/2364566/and-in-clojure?rq=1 çünkü bu soru sorulduktan sonra dil değişmiştir, bu nedenle bu sorudaki örnekler oluşturulmuştur. cevap çalışmaz. Ayrıca soruyu farklı bir bağlamdan sorar –

+0

Bu arada, bu oranlara özgü değildir. '(= 1 1.0)' 'false' döndürür. – Thumbnail

cevap

12

Kullanım ==: == sadece sayılar için ve eğer atar

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

rağmen akılda tutmak bir şey olmayan bir sayı verildi.

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

Cevabınızın gösterdiği gibi, '(==: 1: 1)' bir istisna atar. Sahte dönüş yapmaz - eskiden olduğu gibi - ya da başka bir şey. – Thumbnail

+0

Maalesef, test ettikten ve örneği ekledikten sonra cevabımı değiştirmeyi unuttunuz. –

2

Clojure onlar yuvarlama hataları duyarlı konum olarak yüzen uzak tutmak zor çalışır:

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

Yani karşılaştırma içten 1.5 temsil etmek hiçbir kesin yolu yoktur olmasıdır başarısız gerçek nedeni, ve Clojure ayrıştırıcısının "1.5" bilgisini tükettiği an potansiyel olarak kaybolur. Clojure oranı türüdür içinde,

kesirler kullanarak, bilgi kaybı olmaz, bu yüzden kesir formu 3/2 serbestçe as was the case with the infamous Patriot missile bug.

+2

Hmm. Clojure'ın IEEE 754 binary64 şamandıralarını (Java gibi ve hemen hemen her ana akım dilini) kullandığını farz edelim, '1.5' kesinlikle * * doğru bir şekilde gösterilebilir; '1.4' farklı bir konu olurdu, elbette ... –

+1

tamam, doğru ifadeler o zaman "her seferinde Clojure bir float tükettiğinde, bilgi kaybedilebilir ..." _ _ – ekarak

1

Basitçe söylemek gerekirse kaçak yuvarlama hataları korkusu olmadan diğer fonksiyonlara etrafında geçirilebilir. Çift ya da yüzer ya da bu tür bir şeye dönüştürmeyi denemez. Bu sayede, sayının herhangi bir kesinliği kaybetmeden gerçekte neyi temsil ettiğini koruyabilirsiniz.

Check-out Rich Hickey'nin YouTube'da "Java Programcıları için Clojure" adlı konuşması daha iyi açıklıyor.