2

OverflowExceptionが必要ないときにスローされます(またはそう思います)。オーバーフローしたビットを破棄して、値がオーバーフローすると予想されるいくつかの奇妙な計算を実行しています。ただし、これを適切に機能させることはできないようです。基本的にこれは、巨大なセット (int.MinValue から int.MaxValue へ) を反復するときに発生する i と j の 1 つのペアです。

// i and j are ints
// i is -2147483648
// j is -1
var x = i / j;

// I also tried using unchecked keyword, but it doesn't help    
var x = unchecked(i / j);

アップデート:

-2147483648 / -1 の期待される数学値は 2147483648 です。ただし、この特定のコードは実際には数値を見つけようとはしません。これは、理解するのが少し難しくなった一連のビット操作の一部です。正直なところ、私はその方法を実際に文書化していなかったので、その意図が何であったかさえ知りませんでした. ケースを処理するように設計された特別なコードで意図したとおりに機能することはわかっています。

期待値について:

int は最大で 2147483647 しか保持できないため、オーバーフローを破棄して値 0 を生成することを期待しています。

これについて何か学んだことがあるとすれば、それはおそらく、あいまいなメソッドのドキュメントの重要性です。

4

4 に答える 4

6

これは、この例外が発生する唯一のケースだと思います。Int32オーバーフローできる範囲内の唯一の分割です。(もちろんゼロによる除算もありますが、それは別の例外です。)

したがって、回避したい場合は、このケースに対処するOverflowExceptionだけで済みます。何をしたいですか?この正確なケースを見つけ、それ以外の場合は通常の除算を行うメソッドを作成します。

注: これは、結果を否定するだけで比較を逆にしようとすべきではない理由でもあります。何かを昇順ではなく降順で並べ替えたい場合は、代わりに を-Compare(x, y)使用しますCompare(y, x)。否定は、オーバーフローを与えませんint.MinValue(チェックされたコンテキストにいる場合を除きます) - 黙って を返しますint.MinValue

于 2009-08-19T15:49:26.407 に答える
3

2 の補数は、整数の範囲が 2^32 - 1 から -2^32 であることを意味するため、-2147483648 / -1 は、 では表現できない数値を返しintます。

に入れてみることができますlongvarこの状況でa を使用する理由はありません。

于 2009-08-19T15:39:02.903 に答える
0

これをして。なぜvarここで使うのですか?1文字を節約するために、算術結果のタイプをすべて表示する機能が失われます...

long x = (long)i / j;

飽和が必要な場合は、次のことができます。

int x = (int)Math.Min((long)i / j, int.MaxValue);
于 2009-08-19T16:40:35.883 に答える
0

への/からのキャストを少し行うことで、これを回避できますInt64

var x = (int)((long)i / j);
于 2009-08-19T15:54:02.733 に答える