Clojure中的负小数

Clojure中的负小数,clojure,Clojure,在我的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" 以下是我发现的一种方法,可以发现某个数字何时被视为-0.0: (Math

在我的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"
以下是我发现的一种方法,可以发现某个数字何时被视为-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!
(将十六进制定义为度数[rah ram ras]
{:pre[(>=rah0)(=ram0)(=ras0)(=%0)]
}
(/(+rah(/ram60)(/ras3600))15)
)
(十六进制到度数-1E-400-1E-400-1E-400)
;-0.0 ; 天哪,这里没有失败的断言!
因为赤经(相当于地球经度的天体)没有负值,所以我正在测试后条件是否在某种程度上起作用 保证无论发生什么情况,函数都不会为RA返回负值 我传递给函数的数字。

我怀疑
(=0-1E-400)
在引擎盖下使用了java的
Double.equals()
方法,该方法将正负零视为不相等。这种行为违反了IEEE浮点标准。其他比较运算符转换为符合标准的其他方法,即将+0.0和-0.0视为相等

要获得符合标准的行为,请使用数字等价运算符
=
。因此,
(==0-0.0)
的计算结果为
true

有关Wikipedia上有符号和无符号零的详细信息:


更一般地说:比较浮点数是否相等总是会引起怀疑

请记住,double的行为意味着处理器时间和精度之间的性能折衷。Clojure使使用大小数变得容易,大小数在计算上更昂贵,但具有更好的精度保证。您可以通过在文字编号后添加“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
用户>(类型-1E-400)
java.lang.Double
用户>(类型-1E-400M)
java.lang.BigDecimal
用户>(=0M-1E-400M)
假的
用户>(<0M-1E-400M)
假的
用户>(>=0M-1E-400M)
真的

<代码> > Scala > -1E-400 < 0代码>代码> RES13:布尔=false < /COD> @ USS1690095:Scala认为-1E-400等于0吗?是的,<代码> Scala > -1E-400=0 <代码> RES15:Booale= Trime< /Cord> > Scala不SU。提供与Clojure(Java)相同的问题:
publicstaticvoidmain(String[]args){System.out.println(Double.valueOf(-0D).equals(0D));}//false
这会起作用。但我关心的是整数,至少是函数中的ra和de参数,所以我可以使用'N'后缀。另一方面,性能是我关心的问题,因为这样的函数将被频繁使用。
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