私はC#(.Net 4)でいくつかの統計操作を行っていましたが、メソッドとdouble[]
で奇妙な動作を見つけました。このコードを試してみると:CompareTo
double.NaN
double.NaN.CompareTo(double.NegativeInfinity) //returns -1
それdouble.NaN
はさらに小さいことを意味しdouble.NegativeInfinity
ます!なぜこんな感じなのか誰か説明できますか?
私はC#(.Net 4)でいくつかの統計操作を行っていましたが、メソッドとdouble[]
で奇妙な動作を見つけました。このコードを試してみると:CompareTo
double.NaN
double.NaN.CompareTo(double.NegativeInfinity) //returns -1
それdouble.NaN
はさらに小さいことを意味しdouble.NegativeInfinity
ます!なぜこんな感じなのか誰か説明できますか?
double.NaN
負の無限大未満です。
メタデータ情報から、彼らは次のように説明しました。
public const double NegativeInfinity = -1.0 / 0.0
public const double NaN = 0.0 / 0.0;
メソッドからDouble.CompareTo()
;
このインスタンスを指定された倍精度浮動小数点数と比較し、このインスタンスの値が指定された倍精度浮動小数点数の値よりも小さいか、等しいか、または大きいかを示す整数を返します。
このインスタンスが数値(NaN)ではなく、値が数値の場合
Double.CompareTo()
メソッドは負の整数を返します
このサンプルを見てみましょう(ここにありますDEMO
);
void Main()
{
double a = double.NaN;
double b = double.NegativeInfinity;
Console.WriteLine(a.CompareTo(b));
}
ILコードを見ても、でdouble.NaN
表し、00 00 00 00 00 00 F8 FF
でdouble.NegativeInfinity
表し00 00 00 00 00 00 F0 FF
ます。
IL_0000: ldc.r8 00 00 00 00 00 00 F8 FF
IL_0009: stloc.0
IL_000A: ldc.r8 00 00 00 00 00 00 F0 FF
IL_0013: stloc.1
IL_0014: ldloca.s 00
IL_0016: ldloc.1
IL_0017: call System.Double.CompareTo
IL_001C: call System.Console.WriteLine
CompareToは、あるものが別のものよりも小さいことを通知しません。インスタンスを注文するときに、あるインスタンスが別のインスタンスの前(-)、後(+)、または(0)と交換可能であることを示します。
ここでの理由は、CLRでのプリミティブの設計動作次第です。
IComparableの目的は、タイプのインスタンスを注文することです。したがって、有効なdouble値であるNaNの場合、そのタイプの他のインスタンスの前に注文することが決定されました。
CompareToは、操作よりも大きい/小さい数値と、意味または使用目的が必ずしも同じではないことに注意してください。CompareToは、doubleが引き受けることができる値のセットに対する順序付けを提供することを目的としています。例えば、
double.NaN.CompareTo(double.NaN)
0を返します。しかし
double.NaN == double.NaN
は偽です。同じく、
double.NaN.CompareTo(double.NegativeInfinity)
-1を返しますが、
double.NaN < double.NegativeInfinity
falseを返します。したがって、CompareToメソッドは、数学的にdouble.NaNがdouble.NegativeInfinityよりも小さいと言っているわけではありません。未満の演算子は、実際にはそうではないと言っています。しかし、値を注文するときは、double.NaNが最初に来ると言っています。
DoubleタイプのLessThanOperatorドキュメントへのリンクもあります。これとIComparable.CompareToの意味を並べて読むと、2つのメソッドが表現しようとしていることの違いを明確にするのに役立ちます。
結局のところ、double.nanを数値的に比較しても意味がありません。しかし、doubleのリストがあり、それを使って何かをしたい場合は、リストの最後にすべてを配置して、最初にすべての意味のある作業を実行できるようにし、最初の作業が表示されたら停止できるようにします。これは、一部のアイテムがnullであるリストのようなもので、最後まで押し込まれます。
double.nanが発生するいくつかのケース:
Dim d1 as double = 0/0
Dim d2 as double = Double.PositiveInfinity / Double.PositiveInfinity
Dim d3 as double = Double.PositiveInfinity / Double.NegativeInfinity
Dim d4 as double = Double.PositiveInfinity / Double.PositiveInfinity
Dim d5 as double = Double.PositiveInfinity / Double.NegativeInfinity