0

我们被要求使用堆栈上的内存设计一个 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);
}
4

5 回答 5

2

这实际上取决于 Vector3DStack 的用途。

你可以

  • 抛出异常
  • 使其可配置(也许检查仅在调试模式下发生)
  • 只允许 div 按零返回 Nan - 调用者可以使用 std::isnan() 检查
  • 指定问题。记下调用者有责任不将 s 设置为 0(这称为前提条件)

哪个最好取决于。

于 2013-11-07T13:43:12.013 回答
2

抛出 a std::invalid_argument,它派生自 a std::logic_error; 它通过无效的参数表明程序的逻辑流程有问题。

于 2013-11-07T13:29:43.583 回答
0

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

于 2013-11-07T13:42:00.320 回答
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);
}
于 2013-11-07T13:29:58.130 回答
0

由于您必须从运算符返回一个值,因此您有两种选择:

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

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

于 2013-11-07T13:29:59.840 回答