Ruby Enumerable 无法在 min 函数中比较 BigDecimal NaN

Ruby Enumerable can't compare BigDecimal NaN in min function

如果我这样比较 abc

[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 的可枚举 min uses 的比较运算符,那么我会得到:

irb(main):001:0>  a <=> b
=> nil

irb(main):002:0>  a <=> c
=> nil

并且没有呈现任何错误。这是 Ruby 中的问题还是我误解了 min,是否有其他东西可以用来达到与 enumerable 的 min 相同的效果,但不会爆炸?

来自 Ruby 语言 documentation:

NaN is never considered to be the same as any other value, even NaN itself:

n = ::new(‘NaN’)

n == 0.0 -> nil

n == n -> nil

据我了解,NaN 值的任何实例都是独一无二且无可比拟的。

考虑这个代码片段:

require 'bigdecimal'

a = BigDecimal('NaN')
b = BigDecimal('NaN')

puts a == b
puts a > b
puts a < b

对于这些比较中的每一个,您都会得到 falseminmax 依赖排序来产生结果,正如@phoffer 指出的那样,sort 根据第二个数字是否等于,大于,产生值 0、1 和 -1小于或小于第一个数字。

TL;DR:任何时候在运算中使用 NaN 时,都不会期望得到有意义的结果。

如果 API 你正在使用 returns 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