2

Ruby コア ライブラリには、非常に便利なSetクラスがあります。あらゆるタイプのオブジェクトを格納できます。

しかしご存知のように、( FloatRuby の) 浮動小数点数には精度の問題があります。1.2-1.0等しくありません0.2

s = Set.new()
s.add(1.2-1.0)
s.add(0.2)
s.size
=> 2

はい、type を使用BigDecimalして正確な数値を取得できます。Setしかし、小さなエラー (例: ) に耐えることができるように、特定の比較関数を与えることは可能1e-9ですか?

(この問題は言語にとらわれないことを知っています。他の一般的な言語での解決策を歓迎します)

4

1 に答える 1

1

興味深い質問です。あなたがやりたいことに応じて、潜在的な解決策を見つけたと思います。Ruby は内部で a を使用して、 aHashの要素を格納しSetます。Ruby では、Hashキーの等価性はhashおよびメソッドによって定義されeql?ます。したがって、Float(emptor に注意してください!) でこれらのメソッドを再定義すると、Set合理的に近いFloats が等しいと見なすことができます。

class Float

  def eql?(other)
    other.is_a?(Float) && self.round(9) == other.round(9)
  end

  alias :old_hash :hash

  def hash
    self.round(9).old_hash
  end

end

s = Set.new
s.add(0.2)
s.include?(0.2)       # => true
s.include?(1.2 - 1.0) # => true
s.include?(0.2001)    # => false
于 2012-04-15T14:12:44.953 に答える