2011-11-07 6 views
2

オーバーフロー時に値を制限する必要があります。次のように 私はこれを実装:C#値オーバーフロー制限

public static sbyte LimitValueToSByte(this int val) 
    { 
     if (val > sbyte.MaxValue) return sbyte.MaxValue; 
     if (val < sbyte.MinValue) return sbyte.MinValue; 
     return (sbyte)val; 
    } 

は、よりエレガントな方法はありますか?

これはタイムクリティカルなシステムのコードなので、パフォーマンスが重要です。

答えて

0

この問題の私の新しいソリューション:

public static sbyte Clamp(this int val) 
{ 
    return (sbyte)Math.Max(Math.Min(value, sbyte.MaxValue), sbyte.MinValue); 
} 
3

これは完全に読み取り可能で有効なコードのように見えますが、改善は必要ありません。それはメソッドの名前です。おそらくLimitValueToSByteではなくToSbyteを使用してください。

1

この機能をより良く書く方法は考えられません。

この種の制限操作は通常Clampと呼ばれているので、ClampToSByteと呼びます。 Limitは少し特殊性が低く、ラッピングなどの他の境界条件が可能です。

同様のコードを浮動小数点数に実装する場合は注意が必要です。具体的には、NaNと符号付きの0に対して、どのような振る舞いをするかを決める必要があります。しかし、幸いにも積分値に問題はありません。

+0

署名ゼロはいけません問題である。 – SLaks

+0

@Slaks整数ではありません。しかし '(-0.0).Clamp(0,1)'は '-0'を返しますが、これはすべての状況で望ましくないかもしれません。 – CodesInChaos

+1

署名付きゼロは認識していますが、ここでは問題は発生しません。 .Netでは、 '-0.0'は' 0.0'と区別できません。 – SLaks

0

非常によく見えます。よりエレガントなものをお望みなら、一般的なクランプ機能はどうですか?

public static T Clamp<T>(this T value, T min, T max) 
    where T : IComparable<T> 
{ 
    if (value.CompareTo(min) <= 0) return min; 
    if (value.CompareTo(max) >= 0) return max; 
    return value; 
} 

(警告:私はこれをテストしていない。)あなたはこのようにそれを使用することができます。

int a = 42; 
sbyte b = (sbyte)a.Clamp(sbyte.MinValue, sbyte.MaxValue); 
+0

私は 'IComparable 'を使ってバリュータイプのボクシングを避けます。 – CodesInChaos

+0

@ CodeInChaos:私はボクシングを防ぐことは考えていませんでした。ありがとう。 –