在clojure中检查NaN

时间:2013-04-21 00:50:58

标签: clojure floating-point nan

我有一些算法由于某种原因吐出NaNs,我想暂时过滤掉这些不好的结果,稍后再去找出问题。因此,我需要检查一个值是否为NaN,我该怎么做?

我以为我可以使用NaN是唯一不等于自身值的技巧,所以我编写了以下函数

(defn NaN?
  "Test if this number is nan"
  [x]
  ; Nan is the only value for which equality is false
  (false? (= x x)))

如果我问(NaN? Double/NaN Double/NaN),这是有效的。但是,如果值NaN在某些数据结构中(如果是这样),并且在某种意义上已经准备就绪,那么这不起作用。例如

(def test Double/Nan)
(NaN? test)

返回false。

2 个答案:

答案 0 :(得分:7)

使用java静态函数进行这些测试没有任何问题,请尝试。

(Double/isNaN x) 

正如你发现NaN不等于包括它自身在内的任何东西,如果你想忽略NaN值的相等性,你可以删除,替换(参见clojure.walk / prewalk-replace)或明确地测试它们,例如。

(let [nan? #(and (number? %) (Double/isNaN %))
      vec-data [1 Double/NaN]
      map-data {:a 1 :b Double/NaN}]

    [;; compare vectors without NaN values
    (= (remove nan? vec-data) (remove nan? vec-data))

    ;; check that all differences in 2 maps are nan? 
    (every? nan? (mapcat vals (take 2 (clojure.data/diff map-data map-data))))])

     ;; => [true true]

答案 1 :(得分:1)

以下使用==做了

(defn NaN?
  "Test if this number is nan"
  [x]
  ; Nan is the only value for which equality is false
  (false? (== x x)))

更简单地说,我们可以使用Double / isNaN