diff --git a/src/main/cljs/cljs/core.cljs b/src/main/cljs/cljs/core.cljs index 4b9ecc521..0afb3d475 100644 --- a/src/main/cljs/cljs/core.cljs +++ b/src/main/cljs/cljs/core.cljs @@ -960,6 +960,16 @@ h1 (m3-mix-H1 m3-seed k1)] (m3-fmix h1 4)))) +(defn hash-long [high low] + (bit-xor high low)) + +(defn hash-double [f] + (let [arr (doto (js/Float64Array. 1) (aset 0 f)) + buf (.-buffer arr) + high (.getInt32 (js/DataView. buf 0 4)) + low (.getInt32 (js/DataView. buf 4 4))] + (hash-long high low))) + (defn ^number m3-hash-unencoded-chars [in] (let [h1 (loop [i 1 h1 m3-seed] (if (< i (.-length in)) @@ -1021,7 +1031,9 @@ (number? o) (if ^boolean (js/isFinite o) - (js-mod (Math/floor o) 2147483647) + (if-not ^boolean (.isSafeInteger js/Number o) + (hash-double o) + (js-mod (Math/floor o) 2147483647)) (case o ##Inf 2146435072 diff --git a/src/test/cljs/cljs/hashing_test.cljs b/src/test/cljs/cljs/hashing_test.cljs index e40178341..2a2ffcf18 100644 --- a/src/test/cljs/cljs/hashing_test.cljs +++ b/src/test/cljs/cljs/hashing_test.cljs @@ -93,3 +93,12 @@ (deftest test-cljs-1818 (is (= (hash true) 1231)) (is (= (hash false) 1237))) + +(deftest test-cljs-3410 + (testing "Small doubles should not hash the same" + (is (not= (hash-double -0.32553251) (hash-double -0.0000032553251))) + (is (not= (hash -0.32553251) (hash -0.0000032553251)))) + (testing "Same double hashes the same" + (is (= (hash 0.5) (hash 0.5))) + (is (= (hash -0.32553251) (hash -0.32553251))) + (is (= (hash -0.0000032553251) (hash -0.0000032553251)))))