假设您从头开始设计数学库(在JS中):通常的 Vector2 / 3/4 , Matrix2 / 3/4 , Quaternion 等等(WebGL应用程序的标准内容)。处理错误输入的最佳方法是什么? (除以零,反转奇异矩阵,计算2条平行线之间的交点等)。
处理这个问题的两种方法是:
我知道有很多人想知道他们的代码何时失败 - 有些人讨厌动态打字,但我不禁想起可怕的“错误200:除零” 在我多年前编程的早期,我得到了很多例外。唯一的解决方案是使用检查来填充代码以防止任何这些错误。这只是代码UGLY。我也不禁想知道为什么编程语言现在采用 +/- Infinity 和 NaN 。
在这种情况下,尝试执行该行时可能出现的情况:
singularMatrix.invert().add(otherMatrix)
将是:
singularMatrix.invert()
将返回BAD_MATRIX
,而BAD_MATRIX.add()
将无效(并且“停止计算”(类似JQuery))singularMatrix.invert()
会失败,但会保持不变,.add()
可以正常工作singularMatrix.invert()
会用 +/- Infinity 填充矩阵,计算将继续我个人更喜欢后一种选择之一,但我完全乐于接受争论和选择(这就是我在这里问SO的原因)。 我不知道这种事情的“最佳方式”是否已被发明。
答案 0 :(得分:2)
无论你做什么,都不要默默地失败。如果结果出错,继续计算是没有意义的,并且您不希望向用户显示不正确的结果并声称它是正确的。在可重用的库中,尤其是没有什么好处,你不一定知道调用者会对结果做什么。
抛出异常或返回调用者可以检查的特殊值,例如undefined
。
答案 1 :(得分:1)
NaN和状态代码(选项3)
创建IEEE754标准是为了以完全一致的方式解决许多这些问题。例如,1/0 == + inf,这是一种NaN。该标准已经融入处理器本身。它既不是抛出的异常(这会使一些简单的代码变得非常复杂),也不会是一个无声的失败。您可以将NaN一直追溯到它们出现的位置,为您提供修复错误所需的调试信息。
对于像矩阵求逆这样的大型例程,数值库通常遵循返回状态代码的unix约定。在Javascript中,您可以通过返回具有status属性的对象来完成此操作。
举个例子:
singularMatrix.invert().add(otherMatrix)
如果invert
要返回一个带有状态属性'无效矩阵'的充满NaN的矩阵对象,则可以调用add
并返回另一个充满NaN的矩阵。< / p>
这允许您拨打invert
并稍后检查它是否有效;如果您使用例外,您必须立即处理它们,并且当您想要将决定推迟到以后,您必须设置相同的属性集。
在矩阵中仍有部分或全部用NaN填充的有用信息 - 形状信息可用于创建新矩阵以替换错误的初始向量,或者已知的良好值仍可用于计算。
TLDR:执行NaN操作,并在矩阵中重新创建它。