如果我比较a
,b
和c
这样
[a,b,c].min
哪里
a = BigDecimal.new("NaN")
b = BigDecimal.new("NaN")
c = BigDecimal.new("0.0")
我得到:
ArgumentError: comparison of BigDecimal with BigDecimal failed
但是,如果我使用 ruby 的枚举最小值使用的比较运算符,那么我会得到这个:
irb(main):001:0> a <=> b
=> nil
irb(main):002:0> a <=> c
=> nil
并且不会呈现任何错误。这是 Ruby 内部的问题还是我误解了min
,我可以使用其他东西来实现与 enumerable 的min
相同的效果,并且不会爆炸?
来自 Ruby 语言文档:
NaN 从不被视为与任何其他值相同,即使 NaN 本身:
n = ::new('NaN')
n == 0.0 -> 无
n== n -> nil
据我了解,NaN
值的任何实例都是唯一且无与伦比的。
请考虑以下代码片段:
require 'bigdecimal'
a = BigDecimal('NaN')
b = BigDecimal('NaN')
puts a == b
puts a > b
puts a < b
对于这些比较中的每一个,您都会得到false
。 min
和max
依赖于排序来产生结果,正如@phoffer指出的那样,sort
根据第二个数字是否等于、大于或小于第一个数字生成 0、1 和 -1 的值。
TL;DR:任何时候你在操作中使用 NaN,你都不能期待有意义的结果。
如果您正在使用的 API 返回 NaN,您至少可以通过检测它来保护自己免受这种极端情况的影响。NaN 实际上是 Float
的一个实例,因此您可以使用 nan?
方法对其进行测试。
2.2.0 :002 > require 'bigdecimal'
=> true
2.2.0 :003 > a = BigDecimal('NaN')
=> #<BigDecimal:7fae1b3bd050,'NaN',9(9)>
2.2.0 :004 > a.nan?
=> true