3

なぜこの代入はcomileエラーを生成するのですか?この場合Constant value '-2147483648' cannot be converted to a 'ulong'に使用する必要がありますか?unchecked (...)

ulong xDummy30 = (1 << 30); // works
ulong xDummy31 = (1 << 31); // ERROR 25 Constant value '-2147483648' cannot be converted to a 'ulong'
ulong xDummy32 = (1 << 32); // works

代わりにこれを使用すると動作します:

ulong xDummy31a = unchecked((ulong)(1 << 31));
// or
ulong xDummy31b = (1ul << 31); //  comment from Regis Portalez


質問を編集C# でビット演算を行うときに 0 (ゼロ) をキャストする必要があるのはなぜですか? 同様の答えがあり、観察された動作の理由は同じです。しかし、それらは異なる質問です。

4

3 に答える 3

6

MSDN ulong リファレンスによると、すべての整数リテラル 1、30、31 は int と見なされます。

整数リテラルにサフィックスがない場合、その型は、その値を表すことができるこれらの型の最初の型になります: int、uint、long、

MSDN << operatorによると、 << 操作の結果も int です。30 シフトすると結果は正になり、31 シフトすると結果は負の int になり、ulong に割り当てることはできません。

編集:HVDは次のエラーを指摘しました。ありがとうHVD!

開始エラー - 32 ビットをシフトする場合、コンパイラは ulong が必要であることを認識しているため、シフト操作の結果は正の long であり、unlong - end エラーに変換できます。

1<<32 がコンパイラ エラーにつながらない正しい理由は、提供された演算子 << へのリンクにあります。

第 1 オペランドが int の場合、シフト カウントは第 2 オペランドの下位 5 ビットで指定されます。つまり、実際のシフト カウントは 0 ~ 31 ビットです。

32 からバイナリ: 0010 0000; 下位 5 ビット: 0 0000 したがって、実際に実行されるシフトは 1 << 0 であり、結果は値 1 の int になり、もちろん ulong に割り当てることができます。

これを解決するには、番号 1 が長いことを確認してください。その場合、1<<31 は依然として正の long です。

次の規則に従って、サフィックスを使用してリテラルの型を指定することもできます。 L を使用する場合、リテラル整数の型は、そのサイズに応じて long または ulong になります。

したがって、1L は長いです。1L <<31 は正の long であるため、ulong に割り当てることができます

于 2016-05-02T06:59:17.453 に答える
0
    var a = (1<<31);
    Console.WriteLine(a);

    ulong num = unchecked((ulong)(1<<31));
    Console.WriteLine(num);

Output:
-2147483648
18446744071562067968

1<<31 の値は uInt64 に収まりません

https://dotnetfiddle.net/Widget/TfjnSZ

于 2016-05-02T06:44:05.017 に答える