在我的C++項目中,由於數字錯誤,我經常遇到不精確的結果。是否有可能以某種方式重新定義標準比較運算符(==
,<=
,>=
,<
,>
),以便它們不會完全比較但在可接受的錯誤範圍內(例如1e-12
)?重載比較雙以允許數字錯誤
(如果是的話,它是一個好主意,這樣做呢?)
(當然,可以寫的比較功能,但人們直觀地使用運營商。)
在我的C++項目中,由於數字錯誤,我經常遇到不精確的結果。是否有可能以某種方式重新定義標準比較運算符(==
,<=
,>=
,<
,>
),以便它們不會完全比較但在可接受的錯誤範圍內(例如1e-12
)?重載比較雙以允許數字錯誤
(如果是的話,它是一個好主意,這樣做呢?)
(當然,可以寫的比較功能,但人們直觀地使用運營商。)
重載操作符某些參數必須是用戶定義的類型。內置的固定和不可更改。
但即使你能做到,也不會是件好事。幫你一個忙,並提供你的自定義比較「操作員」作爲一組功能,選擇一個名稱,暗示他們使用的策略。如果沒有適當的說明,您不能指望代碼閱讀器知道嚴格等於或者使用DBL_EPSILON或2 * DBL_EPSILON或某些任意的線性或標度容差。
不,你不能重載運營商的建類型。不,改變運營商的語義是(一般來說)不是一個好主意。
你既可以:
double
成員編寫一個包裝類,該成員具有所需的運算符。不能過載標準類型(int
,float
,char
等)
運營商當然,你可以宣佈一類型:
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」。
但您仍在使用標準運算符編寫此代碼。這是不是意味着當浮動\雙重時,新超載的偏差會有相同的偏差? –
是的,我認爲OP只是爲了替代'if(x == y)...'失敗的行爲,因爲x-y是一個非常小的值。對此的常見解決方案是與「epsilon」值進行比較,該值提供「如果差異小於此值,則我們將其視爲相等」。實現你自己的全新浮點算法可能不會更準確[除非你已經研究了多年的主題],並且肯定慢很多[不管你學過多少東西,因爲處理器教師比微代碼/硬編碼指令]。 –
請注意,您的Float類現在違反了比較運算符通常期望的屬性。這意味着您不能將它用於標準容器和算法,其中<必須定義嚴格的弱排序,並且其中==必須是可重複的,對稱的和傳遞的。 – DanielKO
你不能在內建類型上重載運算符,你需要類。 – Mat
這是一個可怕的想法,改變現有的類型不是你的運算符的語義。 – delnan
即使有可能,我也無法想象您可以使用哪種操作員(除了那些明顯的操作員)來獲得您想要的行爲。 –