TDD让我除以零。可以吗?

时间:2016-05-10 11:27:07

标签: c++ visual-studio-2013 tdd divide-by-zero

我使用TDD来开发一个类,其中一个部分看起来像这样

first number :
<input type="text" name="num1" id="value1" />
<br>
<br>second number :
<input type="text" name="num2" id="value2" />
<br>
<br>sum :
<input type="text" name="answersum" id="answer"/>
<br>
<br>

<input type="button" name="add" value="add" onclick="addNumbers()" />

即使调用class A { public: // methods, members, stuff private: std::vector<int> vectorA; std::vector<int> vectorB; bool isAbove(double lowerBound) { double x = (double)vectorA.size() / vectorB.size(); return x > lowerBound; } // more methods, members, stuff }; vectorB.size()实际为0,所有测试都会通过 - 不会抛出任何异常。如果我使用调试信息进行构建并不重要。但是,与isAbove()相比,调试显示x-nan(ind)(正如您所预期的那样)。

我将VS2015与VS2013(v120)工具集一起使用。 ideone.com produces the same result

我应该在计算lowerBound之前检查vectorB.size() == 0,但是(通过TDD的过程)这不是必需的吗?

2 个答案:

答案 0 :(得分:1)

浮点除零由IEEE 754(几乎可以肯定地定义系统上的浮点运算)定义,它告诉我们x中的结果是“inf”值。这将始终“高于”lowerBound

然而,严格地说,就C ++本身而言,除以零具有未定义的行为。如果您想要绝对安全,并且不介意性能损失,可以通过if语句来避免它。但这完全取决于你。

  

[C++14: 5/4]:如果在评估表达式期间,结果未在数学上定义或未在其类型的可表示值范围内,则行为未定义。 [注意:大多数现有的C ++实现忽略整数溢出。除零处理,使用零除数形成余数,所有浮点异常因机器而异,通常可通过库函数调整。 -end note]

     

[C++14: 5.6/4]: [..] 如果/或%的第二个操作数为零,则行为未定义。 [..]

答案 1 :(得分:1)

浮点除以零在C ++中给出了未定义的行为,因此您获得的任何结果都是正确的(至少在标准C ++中)。没有要求在除以零时产生特定值或产生任何信号。

您描述的行为与使用IEEE浮点的实现一致,其中正数除以零将得到正无穷大,负数除以零将得到负无穷大,零除以零将给出NaN(非a数)[这是一种过度简化,因为IEEE表示允许表示正负零,但只需将std::vector的大小转换为{,就不会得到负零。 {1}}]。

你真的需要测试double在除以它之前是非零的。

或者,vectorB.size()给出(数学上)等效结果而没有任何除法 - 唯一可能的问题是计算return vectorA.size() > lowerBound*vectorB.size()中的溢出(可以通过对{{1进行范围检查来解决) }和/或lowerBound*vectorB.size())。