适当的行为以防止被零除

时间:2013-11-07 13:26:19

标签: c++ division divide-by-zero

我们被要求使用堆栈上的内存设计Vector3D类。我需要将矢量除以标量,但是什么是防止除以零的最合适的行为?我可以抛出异常?我不想返回(0,0,0)的Vector3D,因为这表明操作是成功的,而实际上并非如此。

Vector3DStack Vector3DStack::operator / (float s) const
{
    if (s == 0)
    {
        // How should I handle division by zero?
        // Method is expecting a Vector3DStack to be returned.

    }

    return Vector3DStack(x / s, y / s, z / s);
}

5 个答案:

答案 0 :(得分:2)

抛出一个std::invalid_argument,它来自std::logic_error;它表示程序的逻辑流程有问题,通过无效的参数。

答案 1 :(得分:2)

这实际上取决于Vector3DStack将用于什么。

你可以

  • 抛出异常
  • 使其可配置(可能仅在调试模式下检查)
  • 只允许div为零返回一个Nan - 调用者可以用std :: isnan()检查
  • 指出问题。记下调用者的责任是它没有将s设置为0(这称为前置条件)

哪个最好取决于。

答案 2 :(得分:0)

你绝对应该抛出异常。这就是例外 - 表示代码中的特殊情况。实际上,您也可以允许零容差,例如:

Vector3DStack Vector3DStack::operator / (float s) const
{
    if (fabs(s) < 1e-10) {
      ... throw some exception to indicate you are dividing a vector by zero.
    }
    return Vector3DStack(x / s, y / s, z / s);
}

答案 3 :(得分:0)

由于必须从运营商返回值,因此您有两种选择:

  1. 抛出异常(绝对是首选)
  2. 返回由三个NaN s。
  3. 组成的向量

    顺便说一句,你不应该 chceck,浮点值是否等于为零,因为你会得到很多假阴性。由于特定的浮点算术,你应该将除数与一个非常小的值(一个比你在算法中使用的任何一个小的值)进行比较 - 例如,如果你对1e-9值进行操作,选择{{ 1}})。

答案 4 :(得分:0)

适当的行为取决于函数的规范。该函数可以在没有任何检查的情况下编写(这适用于符合IEEE标准的浮点数学);它可以检查0并抛出异常;它可以检查0并中止;它可以检查0并简单地返回。所有这些行为都是合理的,如果没有上下文,就不可能说出最佳选择。这就像问“我要去旅行;我应该开车还是飞行?”。