75853


### 【状況】

  * **Price** ：商品価格（`decimal`型） データグリッドに保持。
  * **Count** ：商品数量（`int`型） テキストボックスにユーザーが入力する
  * **Amount** ：税込み金額（`decimal`型）

上記の価格 **Price** と数量 **Count** から税込み金額 **Amount** を算出するコンポーネントを作成しています。  
現実には起こりにくいと思いますが、  
**Price** と **Count** が共に大きい場合、 **Amount** が`decimal.MaxValue`を超えるおそれがあります。  
これを回避する処理を書き、下記ケースではテストに成功しました。  
私のとった手法は、積を一度`double`型で受けて`decimal`型に変換可能か`try~catch`で確認する方法です。

### 【質問】

[過去の質問](https://ja.stackoverflow.com/questions/6711)にもあるように、  
`double`型で金額を計算するのはまずいという認識がありますが、  
`decimal`型のオーバーフローを確認する方法として下記は一般に成立しますか？  
成立しないような気がするのですが、他に方法も思いつきません。  
趣味の範囲ですが、よろしくお願いします。

[code]

    /***** constants *****/
    const int TAX_RATE = 10;
    
    /***** input_start *****
    (decimal) Price    = 792280000000000000000000000
        (int) Count    = 100
     *****  input_end  *****/
    
    
    private decimal _amount;
    public decimal Amount
    {
        get { return _amount; }
        set { amount = value; }
    }
    private decimal _price;
    public decimal Price
    {
        get { return _price; }
        set { _price = value; }
    }
    private decimal _cnt;
    public decimal Cnt
    {
        get { return _cnt; }
        set
        {
            int Count = value;
    
            double dTaxAmount = Convert.ToDouble(Convert.ToDouble(Price) * TAX_RATE * 0.01d * Count);
            double dTemp = Convert.ToDouble(Price * Count) + dTaxAmount;
    
            decimal mTemp = 0;
            try
            {
                mTemp = Convert.ToDecimal(dTemp);
            }
            catch (OverflowException)
            {
                Console.WriteLine("注文可能金額を超えています。");
                return;
            }
    
            decimal mTaxAmount = Convert.ToDecimal(Convert.ToDouble(Price) * TAX_RATE * 0.01d * Count);
            _amount = Convert.ToDecimal(Price * Count) + mTaxAmount;
            _cnt = value;
        }
    }
    
[/code]

### 【参考】

decimal ±1.0 × 10^-28 から ±7.9228 × 10^28 28 から 29 桁の数字 16 バイト System.Decimal  
[組み込みの数値変換 (C# リファレンス)](https://docs.microsoft.com/ja-
jp/dotnet/csharp/language-reference/builtin-types/numeric-conversions)  
[浮動小数点数値型 (C# リファレンス)](https://docs.microsoft.com/ja-
jp/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-
types)


CC BY-SA 4.0
2021-05-15T13:25:45.660
75850
2021-05-15T15:24:28.837
2021-05-15T15:24:28.837
38266
38266
question
c#
C#のdecimal 型のオーバーフロー確認について


[`checked`ステートメント](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-
reference/language-specification/statements#the-checked-and-unchecked-
statements)や[`checked`演算子](https://docs.microsoft.com/ja-
jp/dotnet/csharp/language-reference/language-specification/expressions#the-
checked-and-unchecked-operators)を使えば`OverflowException`が発生するので悩む必要もないかと。

[code]

    try {
        _amount = checked(Price * (1 + TAX_RATE * 0.01m) * Count);
    }
    catch (OverflowException) {
        Console.WriteLine("注文可能金額を超えています。");
        return;
    }
    
[/code]


CC BY-SA 4.0
2021-05-15T13:47:45.433
75853
2021-05-15T14:06:03.407
2021-05-15T14:06:03.407
4236
4236
75850
answer