8

Clojureの研究中に、私はこれを見つけました:

;Clojure 1.4.0
(def neg_inf -1E-400)
(cond
    (= neg_inf 0) "Zero"
    (< neg_inf 0) "Negative"
    (> neg_inf 0) "Positive"
    :default "Neither"
)
;#'user/neg_inf
;user=> "Neither"

バグですか?

次に、試しました:

(Math/signum -1E-400) ;-0.0

いくつかの数値が -0.0 と見なされるときに発見した方法を次に示します。

(Math/copySign 1. -0.) ;-1.0
(Math/copySign 1. -1E-99999999999999999999999);-1.0

このようにして、数値が途方もなくゼロに近い場合でも、数値が負かどうかを知ることができます。

これはすべて、この問題を解決しようとしていたためです。

(defn hexadecimal-to-degrees [rah ram ras]
     { :pre [ (>= rah 0) (< rah 24) (>= ram 0) (< ram 60) (>= ras 0) (< ras 60) ]
       :post [ (>= % 0) ]
     }
     (/ (+ rah (/ ram 60) (/ ras 3600)) 15)
)

(hexadecimal-to-degrees -1E-400 -1E-400 -1E-400)
;-0.0 ; OMG, no Assert failed here!

赤経 (地球の経度に相当する天体) には負の値がないため、関数に渡した数値に関係なく、関数が RA に負の値を返さないことを保証する方法で事後条件が機能するかどうかをテストしていました。関数..

4

2 に答える 2

8

(= 0 -1E-400)私は、正と負のゼロを等しくないものとして扱うJava のDouble.equals()メソッドを内部で使用していると思われます。この動作は、IEEE 浮動小数点標準に違反しています。他の比較演算子は、標準に従って動作する他のメソッドに変換されます。つまり、+0.0 と -0.0 を等しいものとして扱います。

標準に準拠した動作を得るには、数値等価演算子を使用します==。したがって、 に(== 0 -0.0)評価されtrueます。

ウィキペディアの符号付きゼロと符号なしゼロの詳細: http://en.wikipedia.org/wiki/Signed_zero

より一般的な注意事項: 浮動小数点数を比較して等しいかどうかは、常に疑惑を引き起こすはずです。

于 2012-09-18T12:06:05.920 に答える
2

Doubles の動作は、プロセッサ時間と精度の間のパフォーマンスの妥協を意味することに注意してください。Clojure を使用すると、BigDecimals を簡単に操作できます。BigDecimals は、計算コストが高くなりますが、精度が保証されます。リテラル番号の後に「M」を追加することで、BigDecimal 数値リテラルを指定できます。すべての数値演算子は BigDecimal を受け入れます。あなたの例に関連するクイックテストドライブ:

user> (type -1E-400)
java.lang.Double
user> (type -1E-400M)
java.lang.BigDecimal

user> (= 0M -1E-400M)
false
user> (<= 0M -1E-400M)
false
user> (< 0M -1E-400M)
false
user> (>= 0M -1E-400M)
true
于 2012-09-18T15:42:02.510 に答える