簡體   English   中英

C ++處理零除的最佳方法

[英]C++ Best way to handle division by zero

我正在編寫一個C ++類,該類在向量中存儲一些雙精度值(稱為mpValues)並計算其平均值。 構造時,值數組為空,因此執行此計算將返回0.0 / 0.0。

我決定要求零值的均值是錯誤的。 因此,最好返回NaN並顯示錯誤消息,以使用戶意識到該問題。 代碼如下:

double Average::CalculateAverage() const
{
    if(mpValues->size() == 0){
        std::cerr << "Instance of Average at: " << this << " contains no values.\n"
                  << "In this case the arithmetic mean is defined as NaN." <<std::endl;

        return 0.0/0.0;
    }
    else{
        ...calculate the arithmetic mean
    }
}

這是明智的做法,還是您有更好的建議? 通常,我不會那么挑剔,但這是對工作機會的考驗,所以我想避免做出錯誤的決定。

提前致謝!

標准選項是返回NaN,引發異常或返回選項,例如boost :: optional。 每種方法都有其優點和缺點,許多人已對此進行了詳細的審查。 只是不要在函數內顯示錯誤消息,因為這違反了單一責任原則

您已經回答了以下問題:

我決定要求零值的均值是錯誤的。

因此,無需返回NaN或處理零除。 您可以創建自己的異常類(例如EmptyVectorError)並拋出並捕獲它。

這是一個C ++問題,因此我們應該給出一個C ++答案。 根據單一職責原則 (由Don Reba提及),我們得出結論,從您的職能范圍內報告錯誤確實不適合。 有兩個主要選項。

1明確指定使用空容器調用您的average(container)未定義行為 (UB)。 這是C ++ std庫中許多算法的標准做法。 它使您可以忽略空容器的可能性,而只返回sum/size() 您可以添加assert(size()>0); (或類似)在調試模式下。

2在API中明確允許使用空容器(我想這就是您想要的)。 在這種情況下,返回sum/size()是不合適的。 它可能會返回NaN或觸發信號,具體取決於錯誤設置,但是即使NaN也不容易捕獲(我認為isnan()不是標准的庫函數)。 因此,您必須以某種方式以干凈的方式返回未定義的結果。 這可以通過拋出適當的異常或返回類型來完成,例如boost::optional<> (由usta建議),該類型顯式地允許一個未定義的值而不是一個錯誤(與帶有double NaN不同)。

我認為拋出異常是C ++中最合適的方式(如果您選擇選項2)。

我建議將返回類型更改為boost::optional<double>

鏈接到文檔

您有2個選項-返回NaN或引發異常。 您應該做什么,取決於用法。

1)客戶端僅顯示均值:然后,我將選擇簡單地返回NaN。 這樣,客戶端就不會因為自己不打擾的事情而被迫編寫錯誤處理代碼。

2)客戶使用平均值計算新值:這很困難。 通過拋出異常,您可以迫使他明確地處理它。 這可能是一件好事。 另一方面,據我所知,可以在計算中使用雙值NaN。 這也取決於您的其余工作。 如果您始終使用例外,則也應使用例外。 如果您始終使用錯誤代碼,則應使用NaN。 如果混合-應該清理干凈。

PS:我不會寫0.0 / 0.0,而是改用std :: numeric_limits 更容易閱讀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM