2013-05-22 5 views
13

C#でdouble.Nan == double.NaNが常にfalseであることを確認した後、私は平等がどのように実装されたのかが不思議になりました。だから私はダブル構造体を逆コンパイルするReSharperのを使用し、ここで私が見つけたものです:私は「もののSystem.Doubleはいつダブルですか?

public struct Double : IComparable, IFormattable, IConvertible, IComparable<double>, IEquatable<double> 
{ 
    // stuff removed... 

    public const double NaN = double.NaN; 

    // more stuff removed... 
} 

これは、構造体Doubleは、この特別な下ケースdoubleで定義された定数を宣言示しているようですdはいつも2つが完全に同義であると考えました。さらに、私が小文字の二重に実装すると、Resharperは単にファイルの先頭にある宣言にスクロールします。同様に、小文字のNaNの実装にジャンプすると、その行の前の定数宣言に移ります。

だから私はこの一見再帰的な定義を理解しようとしています。これはデコンパイラの人工物ですか?おそらくResharperの限界?あるいは、この小文字の倍数は、実際には違う獣であり、CLR/CTSより低いレベルのものを表していますか?

NaNは本当にどこから来たのですか?

+2

これは関連性がありますか? http://stackoverflow.com/questions/4751885/how-are-the-primitive-types-defined-non-recursivelyまた、http://stackoverflow.com/questions/16113850/if-int32-is-just-an -All32-int-int-how-can-the-int32-class-use-an-int –

+3

メタデータを表示するのにVSを使用するだけで、 'public const double NaN = 0.0/0.0;' –

+1

'NaN'は' Not a 「無限大」と同様に、正または負にすることができます。誰かが不思議に思っている場合に備えて。 – Nolonar

答えて

8

.NETアセンブリのための最良のソースは、ビルドに使用された実際のソースコードです。精度のためにデコンパイラを打ち負かすと、このコメントはかなり役に立ちます。 Reference Sourceをダウンロードしてください。

また、Double.NaNは、Marcが想定しているようにILでは定義されていないことがわかります。実際はC#のソースコードファイルです。コンパイル時に定数式を評価するC#コンパイラを利用しています

public const double NaN = (double)0.0/(double)0.0; 

net/clr/bcl/system/double.csソースコードファイルは本当宣言を示しています。また、NaNはC++コンパイラによって定義されているので、NaNはC#コンパイラを記述するための言語であるため、

15

デコンパイルされたコードを見てください。特に、ビルドされたものの場合は注意してください。ここで実際のILは(.NET 4.5のために、少なくとも)である:これはNaNトークンを介してILに直接処理される。すなわち

.field public static literal float64 NaN = float64(NaN) 
{ 
    .custom instance void __DynamicallyInvokableAttribute::.ctor() 
} 

しかし、それはconst(ILのliteral)であるため、コールサイトに「焼き付けられる」ことになります。 double.NaNを使用する他の場所ではでもfloat64(NaN)を使用してください。同様に、例えば、私がしなければ:これらの割り当て

const int I = 2; 
int i = I; 
int j = 2; 

の両方が(彼らは両方ldc.i4.2になります)最終ILに同じを見ていきます。

このため、ほとんどの逆コンパイラは、イルパターンNaNを認識し、それに相当する言語をdouble.NaNと表記します。しかし、それはコード自体が再帰的であることを意味するものではありません。彼らはたぶん "ただ二重ですか?"というチェックをしていないだけです。結局のところ、これは単に特殊ケースに過ぎず、float64(NaN)はILで認識される値です。再び、これが真実であることを意味しません

[__DynamicallyInvokable] 
public const double NaN = (double) 1.0/(double) 0.0; 

::これは同じ結果を有することができる何かがある単にことをP

ところで、反射板は、としてそれを逆コンパイル。

関連する問題