14

この C コードを見てください。

int main()
{
    unsigned int y = 10;
    int x = -2;
    if (x > y)
        printf("x is greater");
    else
        printf("y is greater");
    return 0;
}
/*Output: x is greater.*/ 

コンピューターが両方を比較すると、x が符号なし整数型に昇格されるため、出力が x の方が大きい理由を理解しています。x が符号なし整数に昇格すると、-2 は 65534 になり、これは明らかに 10 より大きくなります。

しかし、なぜ C# では、同等のコードが反対の結果をもたらすのでしょうか?

public static void Main(String[] args)
{
    uint y = 10;
    int x = -2;
    if (x > y)
    {
        Console.WriteLine("x is greater");
    }
    else
    {
        Console.WriteLine("y is greater");
    }
}
//Output: y is greater. 
4

3 に答える 3

2

C と C# では、整数型が何を表すかについて異なるビューがあります。C のビューに関する議論については、私の回答https://stackoverflow.com/a/18796084/363751を参照してください。C# では、整数が数値または抽象代数環のメンバーを表すかどうかは、「チェックされた算術演算」がオンかオフかによってある程度決定されますが、範囲外の計算で例外をスローするかどうかを制御するだけです。一般に、.NET フレームワークはすべての整数型を数値を表すものと見なし、例外をスローせずに一部の範囲外の計算を実行できるようにすることを除けば、C# はそのリードに従います。

符号なしの型が代数環のメンバーを表す場合、たとえば符号なしの 2 に -5 を追加すると、符号なしの値が生成され、5 に追加すると 2 になります。それらが数値を表す場合、符号なしの 2 に -5 を追加すると、数値 -3 の表現が得られる可能性があります。オペランドをに昇格Int64させるとそれが可能になるため、それがC#の機能です。

ちなみに、演算子 (特に関係演算子!) は常にオペランドを共通の互換性のある型にプロモートすることによって機能し、その型の結果を返す必要があり、また、一般的なタイプ。が与えられfloat f; long l;た場合、比較には少なくとも 3 つの賢明な意味がありますf==l[ lfloat にキャストできる、 にキャストできるlfまたはが にキャストできる整数であり、キャストすると等しいdoubleことを保証できる]。flongl]。あるいは、コンパイラはそのような混合比較を単純に拒否することもできます。私がドルーサーに頼っていたら、もっともらしい意味が1つしかない場合を除いて、コンパイラーはオペランドを関係演算子にキャストすることを禁じられていたでしょう。どこでも暗黙的に変換可能であるものを直接比較可能にする必要があることを要求することは、私見では役に立ちません。

于 2013-09-13T22:51:22.987 に答える