TDD 让我除以零。可以吗?
TDD lets me divide by zero. Is it OK?
我使用 TDD 开发了一个 class,其中一部分看起来像这样
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
};
即使在调用 isAbove()
时 vectorB.size()
实际上是 0
,所有测试也会通过 - 不会抛出异常。我是否使用调试信息构建并不重要。然而,调试显示 x
与 lowerBound
相比是 -nan(ind)
(如您所料)。
我将 VS2015 与 VS2013 (v120) 工具集一起使用。 ideone.com produces the same result.
我是否应该在计算 x
之前检查 vectorB.size() == 0
,尽管(通过 TDD 过程)这不是必需的?
IEEE 754 明确定义了浮点数除以零(它几乎肯定定义了您系统上的浮点运算),它告诉我们 x
中的结果是“inf “ 价值。这将永远在“上方”lowerBound
.
但是,严格来说,就 C++ 本身而言,除以零具有未定义的行为。如果你想要绝对的、可移植的安全,并且你不介意性能损失,你可以通过 if
语句来避免它。但这完全取决于你。
[C++14: 5/4]:
If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined. [ Note: most existing implementations of C++ ignore integer overflows. Treatment of division by zero, forming a remainder using a zero divisor, and all floating point exceptions vary among machines, and is usually adjustable by a library function. —end note ]
[C++14: 5.6/4]:
[..] If the second operand of / or % is zero the behavior is undefined. [..]
浮点数除以零会在 C++ 中给出未定义的行为,因此您得到的任何结果都是正确的(至少在标准 C++ 中)。除以零时不需要生成特定值或生成任何信号。
您描述的行为与您使用 IEEE 浮点数的实现一致,其中正数除以零将得到正无穷大,负数除以零将得到负无穷大,零除以零将给出一个 NaN(非数字)[这是一种过度简化,因为 IEEE 表示允许表示正零和负零,但是您不会通过简单地转换 std::vector
的大小来得到负零至 double
].
您确实需要在除以它之前测试 vectorB.size()
是否为非零。
或者,return vectorA.size() > lowerBound*vectorB.size()
给出了一个(数学上)等效的结果,没有任何除法——唯一的潜在问题是计算 lowerBound*vectorB.size()
中的溢出(这可以通过对 [ 进行范围检查来解决) =15=] and/or vectorB.size()
).
我使用 TDD 开发了一个 class,其中一部分看起来像这样
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
};
即使在调用 isAbove()
时 vectorB.size()
实际上是 0
,所有测试也会通过 - 不会抛出异常。我是否使用调试信息构建并不重要。然而,调试显示 x
与 lowerBound
相比是 -nan(ind)
(如您所料)。
我将 VS2015 与 VS2013 (v120) 工具集一起使用。 ideone.com produces the same result.
我是否应该在计算 x
之前检查 vectorB.size() == 0
,尽管(通过 TDD 过程)这不是必需的?
IEEE 754 明确定义了浮点数除以零(它几乎肯定定义了您系统上的浮点运算),它告诉我们 x
中的结果是“inf “ 价值。这将永远在“上方”lowerBound
.
但是,严格来说,就 C++ 本身而言,除以零具有未定义的行为。如果你想要绝对的、可移植的安全,并且你不介意性能损失,你可以通过 if
语句来避免它。但这完全取决于你。
[C++14: 5/4]:
If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined. [ Note: most existing implementations of C++ ignore integer overflows. Treatment of division by zero, forming a remainder using a zero divisor, and all floating point exceptions vary among machines, and is usually adjustable by a library function. —end note ]
[C++14: 5.6/4]:
[..] If the second operand of / or % is zero the behavior is undefined. [..]
浮点数除以零会在 C++ 中给出未定义的行为,因此您得到的任何结果都是正确的(至少在标准 C++ 中)。除以零时不需要生成特定值或生成任何信号。
您描述的行为与您使用 IEEE 浮点数的实现一致,其中正数除以零将得到正无穷大,负数除以零将得到负无穷大,零除以零将给出一个 NaN(非数字)[这是一种过度简化,因为 IEEE 表示允许表示正零和负零,但是您不会通过简单地转换 std::vector
的大小来得到负零至 double
].
您确实需要在除以它之前测试 vectorB.size()
是否为非零。
或者,return vectorA.size() > lowerBound*vectorB.size()
给出了一个(数学上)等效的结果,没有任何除法——唯一的潜在问题是计算 lowerBound*vectorB.size()
中的溢出(这可以通过对 [ 进行范围检查来解决) =15=] and/or vectorB.size()
).