4

我有将字典作为参数并返回字典的代码。

该代码计算所有双精度值的总和,并使用总和来计算每个值占总和的百分比。它返回一个新的字典,其中百分比连接到键上。

我的 Web 服务器的事件查看器中记录了一些溢出异常。日志记录异常发生在以下代码上Decimal percentage = (Decimal) (pDataPoints[key] / sum * 100); 它说将值转换为小数时发生异常。

我可能会错过什么边缘情况?

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;
}
4

4 回答 4

6

干得好:

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

就像 gdoron 说的那样,你除以 0。但它只对整数抛出异常。对于浮点数,它会导致Double.Infinity. 然后它尝试将无穷大转换为十进制。

于 2012-05-02T15:50:17.780 回答
3
pDataPoints[key] / sum * 100

此计算为您提供的结果太小或太大而无法以十进制存储。您可以捕获此异常并检查此表达式的值是什么。我的建议(因为我无法说出您期望的值):

double percentageValue = pDataPoints[key] / sum * 100;
try
{
    Decimal percentage = (Decimal) percentageValue;
}
catch (OverflowException exception)
{
    //log percentageValue
    throw;
}
于 2012-05-02T15:42:36.627 回答
1

a 的最大值decimal为 79,228,162,514,264,337,593,543,950,335。a double(您的输入值)的最大值是 1.7976931348623157E+308。大概您的某些输入值(或至少是 的结果pDataPoints[key] / sum * 100)导致的值大于最大十进制值。

于 2012-05-02T15:41:17.717 回答
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.

您可以在这里演示上述内容的一个活生生的例子:http ://rextester.com/RRQT60265

于 2012-05-02T15:55:56.450 回答