abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 03:22 | Zajímavý článek

    V aktuálním příspěvku na blogu počítačové hry Factorio (Wikipedie) se vývojář s přezývkou raiguard rozepsal o podpoře Linuxu. Rozebírá problémy a výzvy jako přechod linuxových distribucí z X11 na Wayland, dekorace oken na straně klienta a GNOME, změna velikosti okna ve správci oken Sway, …

    Ladislav Hagara | Komentářů: 0
    dnes 00:11 | Nová verze

    Rakudo (Wikipedie), tj. překladač programovacího jazyka Raku (Wikipedie), byl vydán ve verzi #171 (2024.04). Programovací jazyk Raku byl dříve znám pod názvem Perl 6.

    Ladislav Hagara | Komentářů: 2
    včera 17:44 | Nová verze

    Společnost Epic Games vydala verzi 5.4 svého proprietárního multiplatformního herního enginu Unreal Engine (Wikipedie). Podrobný přehled novinek v poznámkách k vydání.

    Ladislav Hagara | Komentářů: 0
    26.4. 17:11 | Nová verze

    Byl vydán Nextcloud Hub 8. Představení novinek tohoto open source cloudového řešení také na YouTube. Vypíchnout lze Nextcloud AI Assistant 2.0.

    Ladislav Hagara | Komentářů: 12
    26.4. 13:33 | Nová verze

    Vyšlo Pharo 12.0, programovací jazyk a vývojové prostředí s řadou pokročilých vlastností. Krom tradiční nadílky oprav přináší nový systém správy ladících bodů, nový způsob definice tříd, prostor pro objekty, které nemusí procházet GC a mnoho dalšího.

    Pavel Křivánek | Komentářů: 9
    26.4. 04:55 | Zajímavý software

    Microsoft zveřejnil na GitHubu zdrojové kódy MS-DOSu 4.0 pod licencí MIT. Ve stejném repozitáři se nacházejí i před lety zveřejněné zdrojové k kódy MS-DOSu 1.25 a 2.0.

    Ladislav Hagara | Komentářů: 42
    25.4. 17:33 | Nová verze

    Canonical vydal (email, blog, YouTube) Ubuntu 24.04 LTS Noble Numbat. Přehled novinek v poznámkách k vydání a také příspěvcích na blogu: novinky v desktopu a novinky v bezpečnosti. Vydány byly také oficiální deriváty Edubuntu, Kubuntu, Lubuntu, Ubuntu Budgie, Ubuntu Cinnamon, Ubuntu Kylin, Ubuntu MATE, Ubuntu Studio, Ubuntu Unity a Xubuntu. Jedná se o 10. LTS verzi.

    Ladislav Hagara | Komentářů: 14
    25.4. 14:22 | Komunita

    Na YouTube je k dispozici videozáznam z včerejšího Czech Open Source Policy Forum 2024.

    Ladislav Hagara | Komentářů: 3
    25.4. 13:22 | Nová verze

    Fossil (Wikipedie) byl vydán ve verzi 2.24. Jedná se o distribuovaný systém správy verzí propojený se správou chyb, wiki stránek a blogů s integrovaným webovým rozhraním. Vše běží z jednoho jediného spustitelného souboru a uloženo je v SQLite databázi.

    Ladislav Hagara | Komentářů: 0
    25.4. 12:44 | Nová verze

    Byla vydána nová stabilní verze 6.7 webového prohlížeče Vivaldi (Wikipedie). Postavena je na Chromiu 124. Přehled novinek i s náhledy v příspěvku na blogu. Vypíchnout lze Spořič paměti (Memory Saver) automaticky hibernující karty, které nebyly nějakou dobu používány nebo vylepšené Odběry (Feed Reader).

    Ladislav Hagara | Komentářů: 0
    KDE Plasma 6
     (75%)
     (8%)
     (2%)
     (15%)
    Celkem 854 hlasů
     Komentářů: 4, poslední 6.4. 15:51
    Rozcestník

    Zásadní omyl operátoru ==

    19.12.2005 22:45 | Přečteno: 1563× | Plané filozofování | poslední úprava: 19.12.2005 22:55

    O zásadním nedostatku běžných programovacích jazyků a jeho drzém řešení.

    Mějme kód v jazyce C nebo Java:

    double q = 3.0 / 7.0;
    
    if (q == 3.0 / 7.0)
    	print("rovnají se");
    else
    	print("jsou rozdílné!");
    

    Pokud takový kód přeložíte, dostanete v různých prostředích, při různých volbách překladu různé výsledky. To, zda se čísla po porovnání vyhodnotí jako stejná, může záležet třeba na tom, jestli se výpočet provede se skladováním v paměti nebo se vše zvládne v registrech koprocesoru (které jsou 80ti bitové - extended precision). Pokud by bylo q deklarované jako float, čísla se rovnat nebudou, protože 3.0 / 7.0 je double.

    Testovat reálná čísla na rovnost je čiré bláznovství (a naštěstí se to učí i na školách). Operátor == je dobrý leda tak na porovnávání se speciálními hodnotami INF a NaN. Jinak tento operátor nefunguje, jak by člověk očekával. V téměř každé aplikaci je nutné porovnávat s nějakou tolerancí.

    Ternární řešení

    Nemůžu si pomoct, ale v jazycích jako C a Java je to špatně. Operátor == nemá být binární, nýbrž ternární. Dalším operandem má být epsilon, které určí toleranci, se kterou se prvé dva operandy můžou lišit. Tedy:

    double q = 3.0 / 7.0;
    double eps = 1e-6;
    
    if (q == 3.0 / 7.0 : eps)
    	print("rovnají se");
    else
    	print("jsou rozdílné!");
    

    Tento program je správně. Operátor == je zde definován jako abs(X - Y) < EPS.

    Samozřejmě by nastala diskuse, zda má být nějaké epsilon implicitní, zda má být odvozeno od řádů operandů atd.

           

    Hodnocení: 53 %

            špatnédobré        

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    Komentáře

    Vložit další komentář

    19.12.2005 22:54 herhor
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Rika se ternarni, ale to je detail, protoze cele to je blabol. Mam dojem, zes zrovna prisel z nejake prednasky, kde zasvetili do taju reprezentace cisel v pocitaci, tak ses prisel hned ukazat..
    19.12.2005 22:57 paskma | skóre: 13 | blog: Paskmův blog
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Za ternární dík. Blábol? Tak ho vyvrať nějakým věcným argumentem.
    19.12.2005 23:06 herhor
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Jako formalne je to trebas vsechno spravne, nelibi se mi ten styl - nejdriv "zasadni nedostatek beznych programovacich jazyku a jeho drze reseni" - zadny zasadni nedostatek to samozrejme neni, dobry programovaci jazyk neni jako php - nema tam byt operator na vsechno (ani deset druhu porovnani), zadne drze reseni to taky neni, protoze to tak dela kazdy, poznamka o tom, ze "nastesti se to na skolach uci" zni jako ""prosel jsem spoustu skol a vetsinou se to tam ucilo a kde ne tak jsem je na to upozornil"". Dalsi perly "Operátor == nemá být binární, nýbrž ternární." a "Tento program je správně." netreba komentovat.
    19.12.2005 23:24 paskma | skóre: 13 | blog: Paskmův blog
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Pořád čekám na ten věcný argument :-)
    19.12.2005 23:28 herhor
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    OK, nikde nedefinuješ k čemu vztahuješ "správnost" programu. Dovedu si predstavit rozumny a naprosto korektni program, ktery bude vyuzivat toho ze treba (double)(3.0/7) != (float)(3.0/7).
    19.12.2005 23:39 paskma | skóre: 13 | blog: Paskmův blog
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Já tedy ani moc ne. Přijde mi to jako hack. Do řídícího softu k jaderce by ti to QA oddělení nevzalo.

    Nicméně souhlasim, že by bylo potřeba míte nějaký operátor, který porovnává binární obrazy. Ale trvám na tom, že je to potřeba jen v naprosto vyjímečných případech.

    Třeba v Adě95 je problém dostat se na jednotlivé bitíky i u celých čísel. Mj proto, že celé číslo si tam nadefinuješ jak chceš

    type Jablka is range 1..200;

    A houby víš, jestli bude podkladový typ fyzicky char, short, int nebo long. Pro práci s bity jsou tam pak nějaké funkce.

    Uznávám, že mnou navrhovaná fíčura by se hodila spíš do té Ady, než do low-level C.
    20.12.2005 00:28 Miloslav Ponkrác | blog: miloslavponkrac
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    No jo, podobně se dají definovat celá čísla třeba v Pascalu.

    Já bych hlavně řekl, že operátory se nemají zmnožovat, pokud k tomu není vážný důvod. Pokud sám velký paskma (to oslovení myslím samozřejmě v dobrém) má tendenci definovat další a další operátory, vřele mu doporučuji se začít věnovat jazyku APL a zasvětit mu celý svůj život. Tento jazyk jej zejména množstvím operátorů a jeho možnostmi ve výpočtech zajisté zaujme natolik, že v ničem jiném už nebude chtít napsat ani řádku :-) howgh
    20.12.2005 00:46 paskma | skóre: 13 | blog: Paskmův blog
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Že to slyším zrovna od takového fanouška přetěžování operátorů :-)
    20.12.2005 01:06 Miloslav Ponkrác | blog: miloslavponkrac
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Jsem fanoušek přetěžování operátorů, ale tam, kde to přispívá k přehlednosti a efektivitě.

    Řeknu to tak. Mám rád sex, ale kdyby ho po mě někdo chtěl tisickrát denně, tak asi začnu odmítat :-) Stejné je to i s operátory. Mám prostě pocit, že pan paskma začíná nahrazovat kvalitu operátorů kvantitou :-)
    JiK avatar 19.12.2005 23:27 JiK | skóre: 13 | blog: Jirkoviny | Virginia
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Tento program je správně.

    Me prijde jakoby to psal nekdo stejne genialni jako samotny pan dokonaly, nedostizny a skvely RNDr. Mgr. Radek Ulhan, CSc.
    19.12.2005 23:30 paskma | skóre: 13 | blog: Paskmův blog
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Hehe. Skoro začínám chápat jeho vášeň pro cenzurování komentářů :-).

    Ten program _je_ správně.
    19.12.2005 23:28 llook | skóre: 8 | blog: l'blog | Prágl
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==

    Tento názor musím podpořit, čím méně operátorů, tím lépe. A od operátoru rovnosti chci, aby porovnával rovnost.

    Stokrát lepší se mi zdá následující drzé řešení:

    double q = 3.0 / 7.0;
    double eps = 1e-6;
    
    if (around(q, 3.0 / 7.0, eps)
        print("asi se rovnají");
    else
        print("jsou rozdílné!");
    10 REM Dej si pauzu... 20 FOR DELAY=1 TO 5000 : NEXT DELAY
    19.12.2005 23:30 Jan Kundrát (jkt) | skóre: 27 | blog: jkt | Praha - Bohnice
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Jak bys s tim ternarnim operatorem porovnaval ostatni typy?
    19.12.2005 23:31 paskma | skóre: 13 | blog: Paskmův blog
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Nijak. Je definovaný jen pro reálná čísla.
    19.12.2005 23:34 herhor
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Ted jsem na neco narazil. Vis o tom, ze zadny bezny programovaci jazyk nema porovnavani pro octoniony?
    19.12.2005 23:44 paskma | skóre: 13 | blog: Paskmův blog
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Většina nemá ani typ pro komplexní čísla. Leda Fortran.
    19.12.2005 23:49 Miloslav Ponkrác | blog: miloslavponkrac
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Většina rozumných programovacích jazyků náhodou komplexní čísla má, dokonce i C, neřku-li C++. A třeba v C++ funguje operátor == i na komplexní čísla. Já, když si probírám programovací jazyky, se kterýma jsem se setkal, tak naopak musím říct, že komplexní čísla chybí jen u menšíny jazyků.
    20.12.2005 00:36 Sinuhet | skóre: 31
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Az na to, ze kdyz se podivate na tu sablonu, tak se to rozpada na x.real == y.real && x.img == y.img. Takze sme tam kde sme byli.
    20.12.2005 00:58 Miloslav Ponkrác | blog: miloslavponkrac
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Ne ne, vážený pane! Je to ještě složitější! Třída complex může obsahovat jako svoji reálnou a imaginární složky libovolné typy! Takže třeba tady je to v pořádku:
    complex<int> x,y;
    // ... nejaky kod
    if (x == y)
    // ...
    
    Ale jak říkám, považuji původní operátor == pro reálná čísla jako lepší. Kromě toho jde vždycky i v komplexních číslech napsat:
    complex<double> x(1,2), y(1,2);
    if (abs(x - y) < epsilon)
    // ...
    
    Díky flexibilitě C++ není rozdíl v práci mezi reálnými a komplexními čísly.
    20.12.2005 01:10 Sinuhet | skóre: 31
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Ale no samozrejme. Ja chtel jen upozornit, ze u komplexnich cisel ma operator porovnani stejny problem, jako u realnych (pokud to tedy nekdo povazuje za problem).
    20.12.2005 06:56 ZAH | skóre: 43 | blog: ZAH
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Upozorním na chápání operátoru == v javě u všech objektů. Tedy i u komplexních čísel. Operátor testuje shodnost objektů(interně ukazatel na objekt). Nikoliv shodnost hodnot. Něco takovéhoto pro porovnání řetězců je úplně špatně
    public boolean textString(String a,String b){
     return a==b;
    }
    
    Vrátí true pouze pro totožné objekty, Pro porovnání hodnot se musí použít
    public boolean textString(String a,String b){
     return a.equals(b);
    }
    
    20.12.2005 11:14 paskma | skóre: 13 | blog: Paskmův blog
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    No vidíš. Ale v C# == porovnává u řetězců _hodnoty_. Sranda, ne?
    20.12.2005 13:43 Martin Beránek | skóre: 33 | blog: mousehouse | Brno
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    no super - nejaka vyhoda?
    never use rm after eight
    20.12.2005 17:55 Miloslav Ponkrác | blog: miloslavponkrac
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    To náhodou beru jako výhodu. Operátor == má porovnávat hodnoty, to je jeho funkce.
    20.12.2005 22:00 Tomáš Bláha
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    No ale v Cčku přece porovnává hodnoty -- ukazatelů na pole znaků.
    20.12.2005 23:46 kar
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Operátor == nakonec vždy porovnává nějaké hodnoty. U jazyků, kde se běžně míchá práce s hodnotami přímo a přes reference, to samozřejmě vede k chaosu. Ve skutečnosti používáš pro každý objekt dva typy porovnání
    1. identita(a) == identita(b)
    2. hodnota(a) == hodnota(b)
    
    První je pravda tehdy a jen tehdy, když jsou a a b tentýž objekt. V C to typicky znamená porovnání referencí (&a == &b), v Pythonu id(a) == id(b). Identita je sice obyčejně též nějaký typ jazyka, čímž se sice porovnání 1. převádí na 2., ale nebývá předefinovatelné. Málokdy má smysl pro výrazy, lze-li ho vůbec provést. Doporučuji se ovšem zamyslet, proč se id(re.match('a', 'b')) == id(re.match('c', 'd')) v Pythonu vyhodnotí jako True.

    Druhé porovnání je to, které si každý typ definuje, jak se mu zlíbí. Zmatek nastává, když default pro 2. je 1., nebo je to ještě hůře jinak pro jednoduché typy a pro složené... V závislosti na duševním zdraví autora třídy nemusí být == transitivní, symetrický ani reflexivní, ale my normální tyto vlastnosti očekáváme, protože jinak to není žádná relace rovnosti.

    Takže na IEEE == mi spíš vadí, že není reflexivní (pro NaN), než že mu chybí nějaké argumenty (co takhle přidat == hneda dva argumenty: relativní a absolutní odchylky?).
    21.12.2005 00:26 Miloslav Ponkrác | blog: miloslavponkrac
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Ano, je-li výraz typu ukazatel, pak v C se samozřejmě porovnávají hodnoty a je to tak v pořádku. Protože u ukazatelů je jeho hodnotou adresa, kterou obsahuje.

    Podle jsou vůbec zvláštní případ v C. C má datový typ pole, ale nelze tam vytvořit proměnnou, nebo výraz typu pole. Jediná možnost je v C používat pro práci s poli ukazatele. Toto je doplněno až v C++, kde existuje šablona vector, která se chová jako regulérní pole a lze jí použít i v proměnných a výrazech. A dokonce disponuje případně i kontrolou mezí pole.

    Takže C/C++ je konzistentní. Operátor == vždy porovnává hodnoty výrazů a nikdy jinak. Je-li potřeba porovnávat adresy, pak si o to musíte říci operátorem &.

    Z tohoto hlediska si nemůžu zvyknout na Javu, protože tam operátor == dělá jednou porovnávání hodnoty, jindy zase porovnání reference. Bohužel stejnou ptákovinu zavedlo i C#, ale tam je to trochu konzistentnější, protože dost tříd si zavádí vlastní operátor ==, který porovnává hodnoty.

    Zato blahořečím z tohoto hlediska C/C++, stejně tak jako PHP, Pythonu a dalším jazykům, které se této chaotické pasti vyhnuly a operátor == tam vždycky porovnává hodnoty. A tak to má být.
    20.12.2005 11:45 barney
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    existuje pojem ako "strojove epsilon".
    jeho hodnota je nejaka konstanta v /usr/include/
    (nepamatam pod akym menom)
    
    a teraz prichadzame na to, ze navrhari javy nepochopili C++
    
    bool operator == (double a, double b) {
      return (nejaky ten zapis s abs a EPSILON);
    }
    
    a situacia je vyriesena k spokojnosti autora ...
    
    poznamka pre javistov:
    skutocne som mohol napisat:
    
    bool operator == (double a, double b) {
      return rand () > 0.5 ? false : true;
    }
    
    ale nie som predsa v sutazi o najhorsi kod ...
    
    20.12.2005 11:51 paskma | skóre: 13 | blog: Paskmův blog
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Strojové epsilon (eps_mach) samotné situaci neřeši. Tato konstanta je definována jako nejmenší číslo takové, že:

    1 + eps_mach > 1

    Tedy eps_mach je obvykle 10^-k, kde k je počet desítkových cifer mantisy. No ale tato konstanta ztrácí smysl, pokud počítáme s čísly třeba 10^10.
    19.12.2005 23:14 Miloslav Ponkrác | blog: miloslavponkrac
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Nechápu, co tímto autor sleduje. Porovnávání reálných čísel je vždycky ošemetné a to se obecně ví. Nechápu, na co si autor stěžuje.

    Stejně tak by mohl autor namítat, že porovnávání funguje špatně pro řetězce, protože je závislé na jazyku a tudíž nefunguje správně.

    Na druhé straně není žádný problém napsat si funkci podobného stylu:
    template<typename FloatType>
    bool compare_with_epsilon
    (FloatType number1, FloatType number2, FloatType epsilon = 1e-7)
    {
      return fabs(number1 - number2) < epsilon);
    }
    
    19.12.2005 23:28 paskma | skóre: 13 | blog: Paskmův blog
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Autorovi jde jen a pouze o to, že sémantika tohoto operátoru je pro většinu případů neužitečná. Porovnávání binární obrazů reálných čísel na rovnost (právě tak to ieee754 definuje) je prostě na nic. Tak proč to neudělat tak, aby to k něčemu bylo?
    19.12.2005 23:44 Miloslav Ponkrác | blog: miloslavponkrac
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Nikoli, sémantika operátoru == je pro většinu případů užitečná. Operátor == je definován jako binární logický operátor, do kterého vstupují dvě hodnoty a vystupuje prostě false/true podle toho, jestli jsou hodnoty stejné. Funguje to univerzálně pro jakékoli typy hodnot.

    Autor pouze určil, že pro malou podmnožinu typů (limitně se blížící k nule při zvětšujícím se počtu typů v programu :-)) týkajících se reálných čísel, a to ještě jenom některých, to jest reálných čísel v plovoucí čárce, kde je porovnávání ošemetné. POkud potřebujete přesně porovnávat reálná čísla, tak buď:

    1) použijete výraz (cislo1 - cislo2) &kt; epsilon pro reálná čísla v plovoucí čárce

    2) použijete jinou reprezentaci reálných čísel, třeba v pevné řádové čárce, kde se dá porovnávat přímo pomocí operatoru ==
    19.12.2005 23:52 llook | skóre: 8 | blog: l'blog | Prágl
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Protože to je operátor na rovnost. Ten "ternární operátor" mi připadá jen jako zvláštním způsobem zapsaná funkce. Takhle by se dali přidat další a další operátory a byl by z toho rozsypaný čaj++.
    10 REM Dej si pauzu... 20 FOR DELAY=1 TO 5000 : NEXT DELAY
    20.12.2005 09:19 petr_p
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Kazdy operator ja funkce a naopak. Rozdil je jen v notaci (infixova vs. prefixova). Kdybyste chtel jit jeste dal, podivejte se na (un)curryfikaci.
    22.12.2005 14:05 llook | skóre: 8 | blog: l'blog | Prágl
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Každý ne. Při volání funkce se vždy nejdřív vyhodnotí všechny argumenty, zatímco u operátorů se nemusí vždy vyhodnotit všechny operandy.

    Vemme si za příklad ternární operátor:
    1 ? 1 : unlink("/boot/vmlinuz");
    Pokud bychom ho nahradili funkcí:
    ternary(1, 1, unlink("/boot/vmlinuz"));
    Už je vidět ten rozdíl? Nebo and(FALSE, fn()) versus FALSE && fn().
    10 REM Dej si pauzu... 20 FOR DELAY=1 TO 5000 : NEXT DELAY
    20.12.2005 12:59 Michal Kubeček | skóre: 72 | Luštěnice
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Autorovi jde jen a pouze o to, že sémantika tohoto operátoru je pro většinu případů neužitečná.

    U jednoho typu z… kolika? Nota bene u typu, který se v mnoha programech ani nepoužije a v mnoha dalších sice použije, ale na rovnost neporovnává…

    19.12.2005 23:44 #Tom
    Rozbalit Rozbalit vše Jedno z mnoha řešení pro C++
    Operátor == lze stejně jako mnohé další přetížit. Porovnání pak může brát v úvahu nepřenosti, toleranci (epsilon) bude třeba nastavit zvlášť.
    19.12.2005 23:48 Sinuhet | skóre: 31
    Rozbalit Rozbalit vše Re: Jedno z mnoha řešení pro C++
    Nevim jak je to jinde, ale v c++ operatory pro vestavene typy (tedy i float a double) nejde menit.
    20.12.2005 00:12 #Tom
    Rozbalit Rozbalit vše Re: Jedno z mnoha řešení pro C++
    To je pravda, ale stačí si nadefinovat typ nový. (Navíc to může být šablona a může tak obsloužit všechny tři typy reálných čísel.)
    20.12.2005 00:26 Sinuhet | skóre: 31
    Rozbalit Rozbalit vše Re: Jedno z mnoha řešení pro C++
    Panenkomarja - a proc by nekdo delal takovou prasarnu?
    20.12.2005 00:33 Miloslav Ponkrác | blog: miloslavponkrac
    Rozbalit Rozbalit vše Re: Jedno z mnoha řešení pro C++
    V Javě je podobná prasárna zakomponována už do jazyka. Sice ne kvůli operátoru ==, ale kvůli jiným věcem. Takže máte základní typy a pak objektové zabalené základní typy přímo ve standardní knihovně :-)
    19.12.2005 23:59 Miloslav Ponkrác | blog: miloslavponkrac
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Když už jsem v tom, tak bych chtěl upozornit na to, že autor také nedomyslel určité nedostatky jeho "ternáního porovnávání". Jeho operátor by měl problémy v případě, že by se do hry začaly vtahovat takové věci, jako je NaN, Inf a další věci.
    20.12.2005 02:03 paskma | skóre: 13 | blog: Paskmův blog
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    No, ten operátor je nadefinovaný přesně tak, jak by to udělal každý programátor porovnávající dvě REÁLNÁ čísla.

    abs(x-y) < eps

    Takže se dostanu do úplně stejných problémů. Zvlášť NaN dělají bordel. Protože NaN == NaN dá v Javě false.
    20.12.2005 02:54 Miloslav Ponkrác | blog: miloslavponkrac
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    To není věc Javy, ale matematické operace pro reálná čísla jsou naprosto přesně definována.

    Tedy platí:

    NaN == NaN dává false NaN != NaN dává také false NaN < NaN dává také false NaN <= NaN dává také false NaN > NaN dává také false NaN >= NaN dává také false

    Stejně tak operace (X je označeno jako normální číslo, tedy ne NaN, Inf a podobné):

    NaN == X dává false NaN != X dává true NaN < X dává false NaN <= X dává false NaN > X dává false NaN >= X dává false

    Pokud bych porovnával váš výraz abs(x-y) < epsilon, pak za předpokladu, že by alespoň jedno z čísel x, nebo y, případně obojí bylo NaN, pak by výraz dával hodnotu false.

    Takže z hlediska chování v případě NaN by se Váš výraz choval korektně, tedy stejně, jako normální operátor porovnávání.
    20.12.2005 11:13 paskma | skóre: 13 | blog: Paskmův blog
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Vždyť já vím.

    Jenže NaN a INF _nejsou_ reálná čísla. To jsou symboly. Nechápu, v čem je problém. Operátor je to stejné jako ta funkce (rozdíl je jen v notaci, jak tu někdo psal). A tu funkci líp nenapíšeš.
    20.12.2005 18:14 Miloslav Ponkrác | blog: miloslavponkrac
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Dobře, buďme tedy přesní, když pan paskma si to přeje. To, co se používá v typech float, double, apod.. nejsou skutečná reálná čísla. Je to pouze počítačová napodobenina reálných čísel, a této napodobenině chybí některé vlastnosti skutečných reálných čísel. Tedy reálná čísla ála ieee754 nejsou skutečná reálná čísla, když budeme přesní. Do reálných napodobenin čísel ve formátu ieee754 patří i hodnoty typu NaN, Inf apod..

    Zbytek Tvé reakce absolutně nechápu. Například jsem nikde netvrdil, že operátory nejsou funkce, apod.. To jako začínáš trpět samomluvou, když reaguješ na něco, co nebylo vůbec řečeno?
    20.12.2005 18:26 paskma | skóre: 13 | blog: Paskmův blog
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Jenže INF (v obyčejné matematice ležatá osmička) taky není reálné číslo. NaN (v obyčejné matematice třeba 0/0) už vůbec ne. Abychom byli přesní :-)
    20.12.2005 18:44 #Tom
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Mnohdy se zavádí rozřířené množiny R* s +- nekonečnem a C* s nekonečnem, když je potřeba taková množina reálných/komplexních čísel, kde jsou nekonečna žádoucí.
    20.12.2005 18:46 Michal Kubeček | skóre: 72 | Luštěnice
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    No a o to právě jde. Že se tu nebavíme o reálných číslech, ale o hodnotách typu float nebo double (pro fajnšmekry možná ještě long double). A tam nekonečna patří, stejně jako NaN. A je nutné, aby se operace chovaly korektně i pro tyto hodnoty.
    20.12.2005 13:03 Michal Kubeček | skóre: 72 | Luštěnice
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Nemluvě o tom, že relace '|x-y| < ε' není tranzitivní, což je vlastnost, kterou by člověk od operátoru == instinktivně očekával. Je to jako overloadovat operátor + tak, že nebude komutativní, nebo = tak, že nebude vracet výsledek. Oboje sice v praxi jde, ale není to moc rozumné…
    20.12.2005 23:02 podlesh | skóre: 38 | Freiburg im Breisgau
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Nemluvě o tom, že relace '|x-y| < ε' není tranzitivní, což je vlastnost, kterou by člověk od operátoru == instinktivně očekával. Je to jako overloadovat operátor + tak, že nebude komutativní, nebo = tak, že nebude vracet výsledek. Oboje sice v praxi jde, ale není to moc rozumné…
    Dobrá připomínka! Dokonce nejen intuitivně: matematicky je ekvivalence relací reflexivní, transitivní a symetrickou.
    20.12.2005 00:25 Petr Zelenka | skóre: 24 | Semice/Stuttgart (Sindelfingen)
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==

    Zdravím,

    možná mi něco uniká, ale tohle řešení podle mě nic neřeší. Místo porovnání dvou nepřesných čísel na rovnost se porovnává rozdíl dvou nepřesných čísel na nerovnost s jiným nepřesným číslem. Kde je rozdíl?

    A teď si uvědomte, jaký je vztah mezi krychlí a motýlem.
    20.12.2005 00:50 paskma | skóre: 13 | blog: Paskmův blog
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Rozdíl je jen a pouze v tom, že takhle by to bylo zadrátované do jazyka s vizí, že by to zabránilo jedné programátorské chybě. Jinak máš samozřejmě pravdu.

    A taky opakuji, že tohle se asi opravdu nehodí třeba do céčka, ale do něčeho komplexnějšího a na vyšší úrovni. Třeba do Ady.
    20.12.2005 01:14 Miloslav Ponkrác | blog: miloslavponkrac
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Ano, v Adě si docela dobře dokážu představit reálný typ s přetížený operátorem porovnání, který by bral v úvahu epsilon.

    Stejně tak si dokážu představit v C++ třídu, která by obalovala reálný typ a přetěžovala by operátor == způsobem, který by též bral v úvahu epsilon.

    Dokážu si představit podobné řešení třeba v Ruby, kde jde ale o globálnější zásah do systému.

    Otázkou pouze je, zda by programátor používající takové typy s upraveným operátorem nebyl překvapen a neudělal jiné programátorské chyby vyplývající z toho, že by prostě takové chování operátoru porovnávání nečekal.
    20.12.2005 11:29 Lukáš Zapletal | skóre: 42 | blog: lzapův svět | Olomouc
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Zcela s tímto návrhem nesouhlasím. Správný kompilátor/IDE na porovnávání dvou floatů/dablů upozorní (alespoň v Javě tomu tak je). Například z nápovědy jednoho integrovaného prostředí:

    This inspection reports any instances of floating-point values being compared with == or !=. Floating point values are inherently inaccurate, and comparing them for exact equality is almost never the desired semantics.

    Mimochodem - operátor funguje bezvadně v jednom případě, a to triviálním případě, kdy je alespoň jeden z operandu nula. Tento případ pokrývá asi 99 % použití tohoto operátoru, to jedno procento jsou ti, kteří neví, jak je reálné číslo v daném jazyku reprezentováno. A ať se na mě nikdo nezlobí, dávat do jazyka jakousi berličku pro pár rádoby "programátorů" je holý nesmysl.
    20.12.2005 11:55 paskma | skóre: 13 | blog: Paskmův blog
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Jo, takže 1-cos(0) == 0 je podle tebe v pořádku? Podle mě tedy v žádném případě.

    Nula je číslo jaké kterékoliv jiné. Tedy nemá nekonečný desetinný rozvoj, to jo.
    20.12.2005 11:58 Lukáš Zapletal | skóre: 42 | blog: lzapův svět | Olomouc
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Aha, špatně jsem se vyjádřil. Myslel jsem x == 0 případně x != 0. Pochopitelně jakékoliv jiné porovnání už se musí dělat pomocí abs().
    20.12.2005 12:04 Lukáš Zapletal | skóre: 42 | blog: lzapův svět | Olomouc
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Já to snad ze sebe nedostanu :-) Míním kontrolu po inicializaci. Každopádně i toto je evidentně nebezpečné (na to 1-cos jsem nemyslel), takže je lepší se tomu úplně vyhýbat.
    20.12.2005 23:12 kar
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Nebezpečného je na tom co?

    Mám operaci, která je dobře definována pro všechna čísla v nějakém okolí nuly, ale pro přesnou nulu se musí počítat zvlášť. Např. x/x, chceš-li něco triviálního (v tomto případě samozřejmě podmínkou s epsilon nic nezkazím, protože výsledek je vždy jedna, ale chci vidět tu nebezpečnost podmínky x == 0.0).
    elviin avatar 20.12.2005 07:46 elviin | skóre: 29 | blog: elviin | Plzeň-Praha
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    Pekny rozbor od Bruce Dawsona.
    20.12.2005 23:07 kar
    Rozbalit Rozbalit vše Re: Zásadní omyl operátoru ==
    No tak já mám třeba program, kde se používá porovnávání doublů == zcela smysluplně a správně: čte totiž několik sad čísel v plovoucí řádové čárce, přičemž některé jsou redundantní, tj. některé sady byly zapsány několikrát a je zapotřebí je najít. K porovnání mohu použít == (mohl bych použít i memcmp()), protože dělá přesně to, co má (nejsou tam Infy a NaNy).

    Založit nové vláknoNahoru

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.