数学库设计决策:抛出异常或静默失败

时间:2014-03-23 15:08:26

标签: math javascript

假设您从头开始设计数学库(在JS中):通常的 Vector2 / 3/4 Matrix2 / 3/4 Quaternion 等等(WebGL应用程序的标准内容)。处理错误输入的最佳方法是什么? (除以零,反转奇异矩阵,计算2条平行线之间的交点等)。

处理这个问题的两种方法是:

  • 抛出异常

我知道有很多人想知道他们的代码何时失败 - 有些人讨厌动态打字,但我不禁想起可怕的“错误200:除零” 在我多年前编程的早期,我得到了很多例外。唯一的解决方案是使用检查来填充代码以防止任何这些错误。这只是代码UGLY。我也不禁想知道为什么编程语言现在采用 +/- Infinity NaN

  • 或无声地失败

在这种情况下,尝试执行该行时可能出现的情况: singularMatrix.invert().add(otherMatrix) 将是:

  1. singularMatrix.invert()将返回BAD_MATRIX,而BAD_MATRIX.add()将无效(并且“停止计算”(类似JQuery))
  2. singularMatrix.invert()会失败,但会保持不变,.add()可以正常工作
  3. singularMatrix.invert()会用 +/- Infinity 填充矩阵,计算将继续
  4. 我个人更喜欢后一种选择之一,但我完全乐于接受争论和选择(这就是我在这里问SO的原因)。 我不知道这种事情的“最佳方式”是否已被发明。

2 个答案:

答案 0 :(得分:2)

无论你做什么,都不要默默地失败。如果结果出错,继续计算是没有意义的,并且您不希望向用户显示不正确的结果并声称它是正确的。在可重用的库中,尤其是没有什么好处,你不一定知道调用者会对结果做什么。

抛出异常或返回调用者可以检查的特殊值,例如undefined

答案 1 :(得分:1)

NaN和状态代码(选项3)

创建IEEE754标准是为了以完全一致的方式解决许多这些问题。例如,1/0 == + inf,这是一种NaN。该标准已经融入处理器本身。它既不是抛出的异常(这会使一些简单的代码变得非常复杂),也不会是一个无声的失败。您可以将NaN一直追溯到它们出现的位置,为您提供修复错误所需的调试信息。

对于像矩阵求逆这样的大型例程,数值库通常遵循返回状态代码的unix约定。在Javascript中,您可以通过返回具有status属性的对象来完成此操作。

举个例子:

singularMatrix.invert().add(otherMatrix)

如果invert要返回一个带有状态属性&#39;无效矩阵&#39;的充满NaN的矩阵对象,则可以调用add并返回另一个充满NaN的矩阵。< / p>

这允许您拨打invert并稍后检查它是否有效;如果您使用例外,您必须立即处理它们,并且当您想要将决定推迟到以后,您必须设置相同的属性集。

在矩阵中仍有部分或全部用NaN填充的有用信息 - 形状信息可用于创建新矩阵以替换错误的初始向量,或者已知的良好值仍可用于计算。

TLDR:执行NaN操作,并在矩阵中重新创建它。