我使用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的过程)这不是必需的吗?
答案 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()
)。