2013-06-23 32 views
3

在我的C++項目中,由於數字錯誤,我經常遇到不精確的結果。是否有可能以某種方式重新定義標準比較運算符(==,<=,>=,<,>),以便它們不會完全比較但在可接受的錯誤範圍內(例如1e-12)?重載比較雙以允許數字錯誤

(如果是的話,它是一個好主意,這樣做呢?)

(當然,可以寫的比較功能,但人們直觀地使用運營商。)

+1

你不能在內建類型上重載運算符,你需要類。 – Mat

+1

這是一個可怕的想法,改變現有的類型不是你的運算符的語義。 – delnan

+0

即使有可能,我也無法想象您可以使用哪種操作員(除了那些明顯的操作員)來獲得您想要的行爲。 –

回答

3

重載操作符某些參數必須是用戶定義的類型。內置的固定和不可更改。

但即使你能做到,也不會是件好事。幫你一個忙,並提供你的自定義比較「操作員」作爲一組功能,選擇一個名稱,暗示他們使用的策略。如果沒有適當的說明,您不能指望代碼閱讀器知道嚴格等於或者使用DBL_EPSILON或2 * DBL_EPSILON或某些任意的線性或標度容差。

1

不,你不能重載運營商的建類型。不,改變運營商的語義是(一般來說)不是一個好主意。

你既可以:

  • 使用比較函數(如你建議你自己)。
  • 圍繞double成員編寫一個包裝類,該成員具有所需的運算符。
1

不能過載標準類型(intfloatchar等)

運營商當然,你可以宣佈一類型:

class Float 
{ 
    private: 
     float f; 
    public: 
     Float(float v) : f(v) {} 
     ... bunch of other constructors. 
     friend bool operator==(Float &a, Float &b); 
     ... more operators here. 
     float operator float() { return f; } 
}; 

bool operator==(Float &a, Float &b) { return (fabs(b.f-a.f) < epsilon); } 
bool operator==(Float &a, const float &b) { return (fabs(b-a.f) < epsilon); } 
     ... several other operator declarations - need on also make operator 

(以上代碼爲「作爲一個想法「,沒有經過測試,可能需要更多的工作才能成爲」好「)。

您當然會需要一些醜陋的typedef或宏來代碼中的「Float」隨處代表「float」。

+0

但您仍在使用標準運算符編寫此代碼。這是不是意味着當浮動\雙重時,新超載的偏差會有相同的偏差? –

+1

是的,我認爲OP只是爲了替代'if(x == y)...'失敗的行爲,因爲x-y是一個非常小的值。對此的常見解決方案是與「epsilon」值進行比較,該值提供「如果差異小於此值,則我們將其視爲相等」。實現你自己的全新浮點算法可能不會更準確[除非你已經研究了多年的主題],並且肯定慢很多[不管你學過多少東西,因爲處理器教師比微代碼/硬編碼指令]。 –

+0

請注意,您的Float類現在違反了比較運算符通常期望的屬性。這意味着您不能將它用於標準容器和算法,其中<必須定義嚴格的弱排序,並且其中==必須是可重複的,對稱的和傳遞的。 – DanielKO