3

算術オーバーフロー (またはアンダーフロー) を検出し、オーバーフロー カウントを取得する最も適切な方法は何でしょうか?

理解を容易にするために を使用しますがbyte、これはintやその他の基本的な整数型でも同じです。ここで、値が 240 で、それに 24 を足したいとします。明らかに算術オーバーフローです。キーワードを使用すると、checkedこれは少なくとも簡単に検出できます...

byte value = 240;
try
{
    checked
    {
        value += 24;
    }
}
catch (OverflowException e)
{
    // handle overflow, get overflow count via % etc.
}

...例外をスローすることによって。

これは私が現在使用しているものです。

ただし、この例外処理はあまり好きではありません。通常、例外は非常にコストがかかるため、最初から回避したいと考えています。とにかく、これはBoneheaded-Exceptionのように思えます。これを事前に検出するためにできる算数の魔法はありますか?

4

3 に答える 3

3

現在の値と最大値の差が加算を行うのに十分な大きさであるかどうかを確認できると思います:

var difference = byte.MaxValue - value;

if(difference >= 24)//OK to add 24
else//will cause overflow

byte.MinValueアンダーフローを検出するには、代わりに値を使用できます。

var difference = value - byte.MinValue;
if(difference >= 24)//OK to subtract 24
else//will cause underflow

これらを念頭に置いて、それらのいくつかの拡張メソッドを作成するところまで行くことができます:

public static class OverflowExtensions
{
    public static bool WillAdditionOverflow(this byte b, int val)
    {
        return byte.MaxValue - b < val;
    }

    public static bool WillSubtractionUnderflow(this byte b, int val)
    {
        return b - byte.MinValue < val;
    }
}

次のように使用できます。

using MyApp.OverflowExtensions;
//...

if(value.WillAdditionOverflow(24))
    //value + 24 will cause overflow

if(value.WillSubtractionUnderflow(24))
    //value - 24 will cause underflow
于 2014-03-24T14:40:46.817 に答える
2

これを逆にしたらどうですか?

byte oldValue = 240;
byte newValue;

unchecked
{
  newValue = (byte)((oldValue + 24) % 255);
}

// if (newValue < oldValue), overflow happened and newValue 
// contains the "amount" of overflow

(おそらく移植性の理由から、 は整数である% 255ため、 はバイトで必要です)byte + byte

これは、追加する数値が値と同じサイズである場合にのみ機能することに注意してください (つまり、両方ともバイトであり、両方とも int です...)。追加に対してのみ機能します。減算の場合は、単純に比較を反転します ( newValue > oldValue)。掛け算では使い物になりません。

この方法の長所は、そもそもオーバーフローを引き起こさないほど大きなデータ型を持つことに依存しないことです。これは、提案されている他の方法のいくつかの弱点です。

于 2014-03-24T14:48:24.053 に答える
2

このようなものはどうですか?

if (byte.MaxValue - 240 < 24)
{
    // handle overflow
}

アンダーフローについては、たとえば、24 - 240 ができるかどうかを確認してください

if (byte.MinValue + 240 > 24)
{
    // handle underflow
}
于 2014-03-24T14:40:38.877 に答える