7

我有一些算法出于某种原因会吐出 NaN,我都想暂时过滤掉这些不好的结果,稍后再去找出问题所在。因此,我需要检查一个值是否为 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)

返回假。

4

2 回答 2

13

使用 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]
于 2013-04-21T07:58:27.713 回答
3

==的以下使用做到了

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

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

于 2013-04-21T01:12:08.900 回答