C ++处理除零的最佳方法

时间:2012-10-03 08:16:02

标签: c++ divide-by-zero

我正在编写一个C ++类,它在向量中存储一些double值(称为mpValues)并计算它们的平均值。构造时,value数组为空,因此执行此计算将返回0.0 / 0.0。

我决定要求零值的均值是一个错误。因此,最好返回NaN并显示错误消息,以便用户了解该问题。 代码如下所示:

double Average::CalculateAverage() const
{
    if(mpValues->size() == 0){
        std::cerr << "Instance of Average at: " << this << " contains no values.\n"
                  << "In this case the arithmetic mean is defined as NaN." <<std::endl;

        return 0.0/0.0;
    }
    else{
        ...calculate the arithmetic mean
    }
}

这是一种明智的做法,还是你有更好的建议?通常,我不会那么挑剔,但这是对工作机会的考验,所以我想避免错误的决定。

提前致谢!

5 个答案:

答案 0 :(得分:6)

标准选项是返回NaN,抛出异常或返回选项,例如boost :: optional。每种方法都有优点和缺点,许多人已对此进行了详细审查。只是不要在函数中显示错误消息,因为这违反了single responsibility principle

答案 1 :(得分:3)

你已经回答了这个问题:

  

我决定要求零值的均值是一个错误。

因此,无需返回NaN或处理零分割。您可以创建自己的异常类(例如EmptyVectorError)并抛出并捕获它。

答案 2 :(得分:1)

这是一个C ++问题,所以我们应该给出一个C ++答案。根据单一责任原则(Don Reba提到),我们得出结论,从函数中报告错误并不合适。有两个主要选择。

1 明确指出,使用空容器调用average(container)未定义的行为(UB)。这是C ++ std库中许多算法的标准做法。它允许您忽略空容器的可能性并返回sum/size()。您可以在调试模式下添加assert(size()>0);(或类似)。

2 明确允许API中的空容器(我认为这是你想要的)。在这种情况下,返回sum/size()是不合适的。它可能会返回NaN或触发信号,具体取决于错误设置,但即使NaN也不容易捕获(我认为isnan()不是标准库函数)。所以你必须以某种方式以一种干净的方式返回未定义的结果。这可以通过抛出适当的异常或返回类型来完成,例如boost::optional<>(由usta建议),它明确允许未定义的值不是错误(与NaN不同double 1}})。

我考虑将异常作为C ++中最合适的方式(如果你选择2)。

答案 3 :(得分:0)

我建议将返回类型更改为boost::optional<double>

Link to Doc

答案 4 :(得分:-1)

您有2个选项 - 返回NaN或抛出异常。你应该做什么,取决于用途。

1)客户端仅显示均值:然后我会选择简单地返回NaN。这样,客户端就不会被迫为他不打扰的事情编写错误处理代码。

2)客户使用均值计算新值:然后很难。通过抛出异常,你强迫他明确地处理它。这可能是一件好事。另一方面 - 据我所知,双值NaN可用于计算。这还取决于你的其他工作。如果您总是使用例外,您也应该使用例外。如果您始终使用错误代码,则应使用NaN。如果你混合 - 你应该清理它。

P.S。:我不会写0.0 / 0.0而是使用std::numeric_limits代替。它更容易阅读。