Porovnání classy jako náhražka za double

Waseihou

Porovnání classy jako náhražka za double
« kdy: 23. 10. 2012, 13:53:23 »
Narazil jsem při kódování na zajímavý konstrukt - operátor pro porovnání classy sloužící jako náhražka za double:
Kód: [Vybrat]
class CMyDouble {
public:
  ...
private:
  double m_val;
};
...
inline int CMyDouble::operator == (const CMyDouble& val) const {
  return m_val <= val.m_val && m_val >= val.m_val;
}

Může mít nějaký význam porovnání bylo uděláno takto a ne pouze jako m_val==val.m_val? Třeba zaokrohlouvání a podobně...
A nebo to patří na hovnokod.cz? Podle mě ano, ale... výše uvedená konstrukce je součástí poměrně komplexního produktu (jméno třídy jsem proto změnil) a takových operátorů máme více. Lidi co to kódili už ve firmě nejsou. Předpokládám proto, že to (nějakou) logiku má. Neví někdo zkušený v C++ co by to mohlo řešit (důsledky zaokrouhlovacích chyb nebo tak něco)?

Jsem zvědavý :D
« Poslední změna: 24. 10. 2012, 20:22:45 od Petr Krčmář »


Waseihou

Re:C++ - operátor == definován jako x>=y && x<=y pro porovnání double
« Odpověď #1 kdy: 23. 10. 2012, 14:01:36 »
No dal jsem to tam, to je tutovka: http://www.hovnokod.cz/894  ;D

Rax

Re:C++ - operátor == definován jako x>=y && x<=y pro porovnání double
« Odpověď #2 kdy: 23. 10. 2012, 14:03:49 »
Může mít nějaký význam porovnání bylo uděláno takto a ne pouze jako m_val==val.m_val? Třeba zaokrohlouvání a podobně...

Na první pohled se zdá že je to naho*no. Jistotu ti ale dá jedině výpis assembleru.

void

Re:C++ - operátor == definován jako x>=y && x<=y pro porovnání double
« Odpověď #3 kdy: 23. 10. 2012, 14:07:08 »
Prijde mi to, jako kdyby nekdo slysel, ze "floaty se prece nikdy nesmi porovnavat na ekvivalenci", tak to takhle salamounsky vyresil  ;)

eMko

  • ****
  • 456
    • Zobrazit profil
    • E-mail
Re:C++ - operátor == definován jako x>=y && x<=y pro porovnání double
« Odpověď #4 kdy: 23. 10. 2012, 14:18:11 »
Tipl bych to na zaokrouhlovací chybu, protože floaty nejsou přesné.

správně by se to mělo řešit přes std::numeric_limits<double>::epsilon().

Něco ve smyslu return std::fabs(val.m_val - m_val) < std::numeric_limits<double>::epsilon();

ale jestli je to rychlejší nebo pomalejší než to uvedené řešení, nevím :)



poiu

Re:C++ - operátor == definován jako x>=y && x<=y pro porovnání double
« Odpověď #5 kdy: 23. 10. 2012, 14:58:24 »
To tipujem na zlé opisovanie z nejakého manuálu.
Tam sa zvykne definovať
Kód: [Vybrat]
class Object
...
inline int operator == (const Object& val) const {
  return sub_object <= val.sub_object && val.sub_object <= sub_object;
}
Tie nerovnosti bývajú na 1 stranu, aby stačilo mať <= na definíciu ostatných nerovností. A potom to niekto videl a zle to opísal, pričom nezohľadnil rozumne porovnateľné dátové typy.

Inkvizitor

Re:C++ - operátor == definován jako x>=y && x<=y pro porovnání double
« Odpověď #6 kdy: 24. 10. 2012, 09:02:48 »
Takže je to celé proto, aby se minimalizovala definice? To by mi jediné v této diskusi dávalo smysl.

To tipujem na zlé opisovanie z nejakého manuálu.
Tam sa zvykne definovať
Kód: [Vybrat]
class Object
...
inline int operator == (const Object& val) const {
  return sub_object <= val.sub_object && val.sub_object <= sub_object;
}
Tie nerovnosti bývajú na 1 stranu, aby stačilo mať <= na definíciu ostatných nerovností. A potom to niekto videl a zle to opísal, pričom nezohľadnil rozumne porovnateľné dátové typy.

Waseihou

Re:C++ - operátor == definován jako x>=y && x<=y pro porovnání double
« Odpověď #7 kdy: 24. 10. 2012, 13:34:24 »
Nikoliv, jedná se o hovnokod, protože takto definovat operátor == přímo na typ double je nesmysl. Dělal jsem si test a nenašel jsem situaciy, kdy by platilo (x==y)!=(x>=y && y<=x). Opravdu nevidím smysl.

poiu

Re:C++ - operátor == definován jako x>=y && x<=y pro porovnání double
« Odpověď #8 kdy: 24. 10. 2012, 13:50:32 »
Takže je to celé proto, aby se minimalizovala definice? To by mi jediné v této diskusi dávalo smysl.
Príspevkom som myslel skôr to, že niekto zle opisoval odniekiaľ, kde sa minimalizovala definícia u iných objektov, kde ide porovnávať len <=.
Ak máš ==, tak použi namiesto takej konštrukcie ==; u primitívnych dátových typov je to ešte oveľa jasnejšie. U doublov/floatov by si si naviac mal dať pozor a uvedomiť si "toto niekedy nebude fungovať, ako sa čakalo" a prepísať to s použitím nejakého epsilon.

Inkvizitor

Re:C++ - operátor == definován jako x>=y && x<=y pro porovnání double
« Odpověď #9 kdy: 24. 10. 2012, 19:58:14 »
Nikoliv, jedná se o hovnokod, protože takto definovat operátor == přímo na typ double je nesmysl. Dělal jsem si test a nenašel jsem situaciy, kdy by platilo (x==y)!=(x>=y && y<=x). Opravdu nevidím smysl.

Takže je to celé proto, aby se minimalizovala definice? To by mi jediné v této diskusi dávalo smysl.
Príspevkom som myslel skôr to, že niekto zle opisoval odniekiaľ, kde sa minimalizovala definícia u iných objektov, kde ide porovnávať len <=.
Ak máš ==, tak použi namiesto takej konštrukcie ==; u primitívnych dátových typov je to ešte oveľa jasnejšie. U doublov/floatov by si si naviac mal dať pozor a uvedomiť si "toto niekedy nebude fungovať, ako sa čakalo" a prepísať to s použitím nejakého epsilon.

Jasně, myslel jsem tu původní (zřejmě učebnicovou) ideu, ze které to opsal. S tím epsilonem nevím, pokud bych to měl dělat opravdu jenom nějaký wrapper double, možná bych se snažil, aby se to chovalo jako double. Chápu, že když člověk transformuje třeba nějaký geometrický útvar a porovnává ho s něčím, dává smysl dát tam nějakou toleranci, ale na takto relativně nízké úrovni bych to asi neřešil a normálně porovnal ta vnořená čísla, ať si s nimi kompilátor/procesor dělá, co dělá obvykle. A kdybych chtěl mít jistotu, že ((x / y) * y) == y, možná bych počítal s racionálními čísly. Je ale fakt, že takto low-level jsem už dlouho nic neřešil a může být dobrý důvod používat double a zaokrouhlovat může být výhodné.