[英]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.