繁体   English   中英

TDD让我除以零。 可以吗

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

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

即使在vectorB.size()isAbove()实际上为0 ,所有测试也会通过-不会引发异常。 是否构建调试信息都没有关系。 但是调试显示,与lowerBound相比, x-nan(ind) (如您所料)。

我将VS2015与VS2013(v120)工具集一起使用。 ideone.com产生相同的结果

我是否应该在计算x之前检查vectorB.size() == 0 ,尽管(通过TDD的过程vectorB.size() == 0

IEEE 754(几乎可以肯定地定义了系统上的浮点运算)对浮点除以零的定义是明确的,IEEE 754告诉我们x的结果是“ inf”值。 这将始终在lowerBound上方。

但是,严格来说,就C ++本身而言,被零除具有不确定的行为。 如果您希望绝对,可移植地安全并且不介意性能下降,则可以通过if语句避免这种if 但这完全取决于您。

[C++14: 5/4]:如果在对表达式求值时,未在数学上定义结果,或者该结果不在其类型的可表示值范围内,则行为不确定。 [注意:大多数现有的C ++实现都忽略整数溢出。 除以零的处理,使用零除数形成余数,并且所有浮点异常在机器之间都不同,通常可以通过库函数进行调整。 —尾注]

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

浮点除以零会在C ++中产生不确定的行为,因此您得到的任何结果都是正确的(至少在标准C ++中)。 不需要除以零就产生一个特定值或产生任何信号。

您描述的行为与您使用IEEE浮点数的实现相一致,其中将正数除以零将得到正无穷大,将负数除以零将得到负无穷大,而将零除以零将得到NaN (非数字)[这是一个过分的简化,因为IEEE表示允许表示正零和负零,但是只要将std::vector的大小转换为double ,就不会得到负零]。

在除以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