简体   繁体   English

TDD让我除以零。 可以吗

[英]TDD lets me divide by zero. Is it OK?

I used TDD to develop a class that in one part looks like this 我用TDD开发了一个看起来像这样的类

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
};

All tests pass even if vectorB.size() is actually 0 when isAbove() is called - no exception thrown. 即使在vectorB.size()isAbove()实际上为0 ,所有测试也会通过-不会引发异常。 It doesn't matter if I build with debug infos or not. 是否构建调试信息都没有关系。 However debugging showed that x is -nan(ind) when compared to lowerBound (as you may have expected). 但是调试显示,与lowerBound相比, x-nan(ind) (如您所料)。

I use VS2015 with VS2013 (v120) toolset. 我将VS2015与VS2013(v120)工具集一起使用。 ideone.com produces the same result . ideone.com产生相同的结果

Should I check for vectorB.size() == 0 before calculating x although (by the process of TDD) this isn't needed? 我是否应该在计算x之前检查vectorB.size() == 0 ,尽管(通过TDD的过程vectorB.size() == 0

Floating-point division by zero is well-defined by IEEE 754 (which almost certainly defines floating-point operations on your system), which tells us that the result, in x , is the "inf" value. IEEE 754(几乎可以肯定地定义了系统上的浮点运算)对浮点除以零的定义是明确的,IEEE 754告诉我们x的结果是“ inf”值。 This will always be "above" lowerBound . 这将始终在lowerBound上方。

However, strictly speaking, in terms of C++ itself, division by zero has undefined behaviour. 但是,严格来说,就C ++本身而言,被零除具有不确定的行为。 If you want to be absolutely, portably safe, and you don't mind the performance penalty, you can avoid it via an if statement. 如果您希望绝对,可移植地安全并且不介意性能下降,则可以通过if语句避免这种if But that's entirely up to you. 但这完全取决于您。

[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. [C++14: 5/4]:如果在对表达式求值时,未在数学上定义结果,或者该结果不在其类型的可表示值范围内,则行为不确定。 [ Note: most existing implementations of C++ ignore integer overflows. [注意:大多数现有的C ++实现都忽略整数溢出。 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++14: 5.6/4]: [..]如果/或%的第二个操作数为零,则行为不确定。 [..] [..]

Floating point division by zero gives undefined behaviour in C++, so any result you get is correct (at least, within standard C++). 浮点除以零会在C ++中产生不确定的行为,因此您得到的任何结果都是正确的(至少在标准C ++中)。 There is no requirement that a particular value be produced, or that any signal be generated, on division by zero. 不需要除以零就产生一个特定值或产生任何信号。

The behaviour you describe is consistent with your implementation using IEEE floating point, in which division of a positive by zero will give a positive infinity, division of a negative by zero will give a negative infinity, and division of zero by zero will give a NaN (non-a-number) [this is an over-simplification as IEEE representation allows representation of positive and negative zeros, but you will not get a negative zero by simply converting a std::vector 's size to double ]. 您描述的行为与您使用IEEE浮点数的实现相一致,其中将正数除以零将得到正无穷大,将负数除以零将得到负无穷大,而将零除以零将得到NaN (非数字)[这是一个过分的简化,因为IEEE表示允许表示正零和负零,但是只要将std::vector的大小转换为double ,就不会得到负零]。

You really need to test that vectorB.size() is non-zero before dividing by it. 在除以vectorB.size()之前,您确实需要测试它是否为非零。

Alternatively, return vectorA.size() > lowerBound*vectorB.size() which gives a (mathematically) equivalent result without any division - the only potential issue with that is overflow in computing lowerBound*vectorB.size() (which can be addressed by doing range checking on lowerBound and/or vectorB.size() ). 或者, return vectorA.size() > lowerBound*vectorB.size() ,它给出(数学上)等价的结果而没有任何除法-唯一的潜在问题是在计算lowerBound*vectorB.size()溢出(可以解决)通过对lowerBound和/或vectorB.size()进行范围检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM