2012-05-02 3 views
4

辞書に引数をとり、辞書を返すコードがあります。パーセンテージを計算するときにオーバーフロー例外がスローされる

コードは、すべてのdouble値の合計を計算し、その合計を使用して、各値が合計の何パーセントであるかを計算します。パーセンテージをキーに連結した新しいディクショナリを返します。

Webサーバーのイベントビューアには、一部のオーバーフロー例外が記録されています。ログは、次のコードで例外が発生したことを記録します。Decimal percentage = (Decimal) (pDataPoints[key]/sum * 100);値を10進数にキャストするときに例外が発生すると報告されています。

どのようなエッジケースがありますか?

public static Dictionary<string, double> addPercentagesToDataPointLabels(Dictionary<string, double> pDataPoints) 
{ 
Dictionary<string, double> valuesToReturn = new Dictionary<string, double>(); 

// First, compute the sum of the data point values 
double sum = 0; 
foreach (double d in pDataPoints.Values) 
{ 
    sum += d; 
} 

// Now, compute the percentages using the sum and add them to the new labels. 
foreach (string key in pDataPoints.Keys) 
{ 
    string newKey = key; 
    Decimal percentage = (Decimal) (pDataPoints[key]/sum * 100); 
    percentage = Math.Round(percentage, ChartingValues.DIGITS_AFTER_DECIMAL_POINT); 
    newKey += " " + percentage.ToString() + "%"; 
    valuesToReturn.Add(newKey, pDataPoints[key]); 
} 

return valuesToReturn; 
} 
+5

私はあなたがあなたのものに 'DivideByZeroException'' 0/0 'とC#のコードをクラッシュすることができます私は 'OverflowException'とあまり良くないんだけど、あなた今すぐ正しい場所にいます... – gdoron

+0

@Rice Flour Cookies - btw、なぜパーセンテージを10進数に変換していますか?あなたがダブルスと一緒にいれば、それはよかったですか? – empi

答えて

5

あなたが行く:

addPercentagesToDataPointLabels(new Dictionary<string, double>(){{"a", 0}}); 

gdoronが言ったように、あなたは0で除算しかし、それは唯一の例外がスローされますints。浮動小数点数の場合、結果はDouble.Infinityになります。その後、無限大を10進数に変換しようとします。

+0

さて、私はそれを今考え出しました。渡された値がすべて0の場合、0で割ります。ただし、両方の値が2倍の場合、0/0はNaNです。 NaNがDecimalにキャストされると、OverflowExceptionがスローされます。私は、これは、例外メッセージが、OverflowExceptionがNaNを10進数にキャストすることによって引き起こされる可能性があることを示唆していない.netフレームワークの欠陥であると考えています。 –

+0

同じ結論に達しましたが、 double.NaN'だが、辞書に1つの入力とその唯一の桁がある場合、同じことが起こることはない。 – Jamiec

1

decimalの最大値は79,228,162,514,264,337,593,543,950,335です。 double(入力値)の最大値は1.7976931348623157E + 308です。おそらく入力値の一部(または少なくともpDataPoints[key]/sum * 100の結果)は、おそらく最大10進値より大きな値になります。

3
pDataPoints[key]/sum * 100 

この計算では、結果が小さすぎるか、大きすぎて10進数で格納できません。この例外をキャッチして、この式の値が何であるかを確認することができます。 私の提案(私はあなたが期待している値が何を言うことができないので):ここでは

double percentageValue = pDataPoints[key]/sum * 100; 
try 
{ 
    Decimal percentage = (Decimal) percentageValue; 
} 
catch (OverflowException exception) 
{ 
    //log percentageValue 
    throw; 
} 
0

実際にはパーセンテージを計算しているだけなので、そのパーセンテージ計算が範囲decimal.MinValue < v < decimal.MaxValueの範囲外になるような真の数字を思いつくのはかなり難しいです。

ただし、常にこのエラーの原因となる値はありますdouble.NaN

あなたのメソッドにこの辞書を渡す場合:

var d = new Dictionary<string,double>(){ 
      {"A",2}, 
      {"B",2} 
     }; 

あなたはかなり正確な結果を得る:

Key:A 50% Value:2 
Key:B 50% Value:2 

は、しかし、この入力にそれを変更:

var d = new Dictionary<string,double>(){ 
      {"A",double.NaN}, 
      {"B",2} 
     }; 

と結果は:

System.OverflowException:値が大きすぎるか、小さすぎてDecimalに使用できませんでした。

これはあなたの大事なケースでしょうか?入力辞書を生成するものはNaNです。

ライブたとえば、あなたが上記のdemonstarteするためにはここにある:http://rextester.com/RRQT60265

関連する問題