4

非常に興味深いものに出くわしたとき、私は自分の Ruby 1.9 コードのいくつかをテストしていました。誰かがなぜこれが起こっているのか説明できることを願っています。

コードは次のとおりです。

inf = Float::INFINITY

x = inf - inf
y = 0.0/0.0

puts "X is #{x}"
puts "Y is #{y}"

puts "X and Y are both NaN." if x.nan? && y.nan?

puts "This is all as we expected, but here is the mystery..."

puts "X is not equal to Y." if x == y

puts "Surprisingly not even X is equal to X." if x == x

そして、これは出力です:

X is NaN
Y is NaN
X and Y are both NaN.
This is all as we expected, but here is the mystery...

2 つの変数に 2 つの異なる方法で NaN 値を割り当てましたが、それらが等しいかどうかをテストしたところ、そうではありませんでした。その後、ある変数がそれ自体と等しいかどうかをテストしましたが、それは真実ではありませんでした。一部の値がそれ自体と等しいと期待するのは論理的ですが、実際にはそうではありません。

これが NaN 値をテストする正しい方法かどうかはわかりませんが、これらすべての背後にあるものと、Ruby がこのように動作する理由は何かを知りたいのですが?

ありがとうございました

4

2 に答える 2

5

考えてみれば、それは論理的に思えます。xある無限大の数から別の無限大の数を引いて得ますか? その結果は?わかりません。

知らないことをどうやって比較するの?

私のロジックをバックアップするために、ここにソースがありますFloat#==

static VALUE flo_eq(VALUE x, VALUE y)
{
    volatile double a, b;

    switch (TYPE(y)) {
      case T_FIXNUM:
        b = (double)FIX2LONG(y);
        break;
      case T_BIGNUM:
        b = rb_big2dbl(y);
        break;
      case T_FLOAT:
        b = RFLOAT_VALUE(y);
#if defined(_MSC_VER) && _MSC_VER < 1300
        if (isnan(b)) return Qfalse;
#endif
        break;
      default:
        return num_equal(x, y);
    }
    a = RFLOAT_VALUE(x);
#if defined(_MSC_VER) && _MSC_VER < 1300
    if (isnan(a)) return Qfalse;
#endif
    return (a == b)?Qtrue:Qfalse;
}
于 2012-07-05T21:20:02.827 に答える
3

Javascript でまったく同じコードを作成します。

x = Infinity - Infinity
y = 0/0
if(!(x==y)) alert("Not equal");
if(!(x==x)) alert("Not equal");

まったく同じ動作になります。そして、この動作は想定されています。2 つの NaN は互いに等しくありません。無限大 - 無限大は [1 つの巨大な数] - [同じ巨大な数] と同じものではなく、2 つの異なる巨大な数です。この手術の結果は誰にもわかりません。つまり、これは NaN です。

ですから、これは間違いではありません。これは数学的にもっともらしい。

また、試してみてください

if(!(NaN==NaN)) alert("Not equal");
if(!(NaN===NaN)) alert("Not equal");

NaN は決して何にも等しくなりません。

于 2012-07-05T21:28:44.823 に答える