zaokrouhlování

Wiring, C++, C, Java, ...
Pravidla fóra
Toto subfórum slouží k řešení obecných otázek kolem programování (konstrukce, knihovny, alokace paměti, ...)
Uživatelský avatar
gilhad
Příspěvky: 778
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: zaokrouhlování

Příspěvek od gilhad » 19 dub 2021, 15:23

Realna cisla jsou proste na pocitaci problem, protoze se muzou ruznym zpusobem nerovnat, i kdyz jsou stejna, mensi muze byt vetsi a tak podobne, podle toho, kde a v jakem presne poradi se to pocita.

A prekladac ma pomerne volnou ruku, jak stim zachazet - v ramci optimalizace muze ruzne prerovnat i operace a v zavislosti na kontextu muze ten samy zapis dokonce dat i vic ruznych vysledku (podle toho, zda nema treba nakesovane nejake mezivysledky jednou tak a podruhe jinak, podle toho, co tomu predchazelo).

Takze porovnavat realna cisla na rovnost je nesmysl, pokud to potrebujes, tak tam musis zahrnout ten interval, ve kterem zohlednis mozne chyby zaokrouhleni.

Porovnavat realna cisla na nerovnost (ostrou ci neostrou) lze, pokud ti nevadi, ze u dvou blizkych vysledku to muze vyjit spatne. (Ale treba ve hre plokud kilometrovy meteorit mines o 1mm, nebo naopak zasahnes je nerozeznatelne a tedy prakticky jedno. Pri porovnavani hodnoty z potenciometru s konstantou je to diky naindukovanemu sumu a prirozene chybe mereni taky celkem jedno.)

Kdyz to jedno neni, tak muzes pouzit mnohem slozitejsi pristupy, kde pocitas se symboly a provedes si optimalizace sam a definovanym zpusobem, nebo pocitas s cisly v nejakem "mene prirozenem tvaru", napriklad retrezci dekadickych cislic/BCD/objekty, ktere ukladaji i moznou chybu vysledku a pri pretizenych operacich na porovnani ji zohledni, s cisly v presnosti treba stovek cifer a jinymi zhuverilostmi - pokud ti to za to stoji :)

A samozrejme je dobre rucne prerovnat operace tak, aby se ti chyby hromadily co nejmin - tedy vyhybat se operacim, kde se presnost vyrazne ztraci.

Kód: Vybrat vše

a= 10000*30000+2*3;
b= 10000*30000+2*2;
c=a-b;
vs.

Kód: Vybrat vše

a= 10000*30000+2*3;
b= 10000*30000+2*2;
c=2*(3-2);

Uživatelský avatar
gilhad
Příspěvky: 778
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: zaokrouhlování

Příspěvek od gilhad » 19 dub 2021, 15:27

ondraN píše:
19 dub 2021, 15:15
Asi metoda toFloat() používá jiný algoritmus převodu než matematická knihovna. Pak by ale mělo fungovat tohle.

Kód: Vybrat vše

Serial.println(String(a,1).toFloat() == String(b,1).toFloat());
Tam jsou obě čísla převedena stejným algoritmem, takže by měl být výsledek true.
Ale u floatů je radno používat pro porovnání >= nebo <= a pak nemůže dojít k podobným překvapením.
No radeji bych porovnaval "a" a "b", nebo "String(a,1)" a "String(b,1)" - cim min konverzi po ceste, tim vetsi sance, ze se nezanese nejaka nepresnost

Nebo "abs(a-b)<0.001"

ondraN
Příspěvky: 932
Registrován: 08 srp 2019, 20:01
Reputation: 0

Re: zaokrouhlování

Příspěvek od ondraN » 19 dub 2021, 15:42

gilhad píše:
19 dub 2021, 15:27
ondraN píše:
19 dub 2021, 15:15
Asi metoda toFloat() používá jiný algoritmus převodu než matematická knihovna. Pak by ale mělo fungovat tohle.

Kód: Vybrat vše

Serial.println(String(a,1).toFloat() == String(b,1).toFloat());
Tam jsou obě čísla převedena stejným algoritmem, takže by měl být výsledek true.
Ale u floatů je radno používat pro porovnání >= nebo <= a pak nemůže dojít k podobným překvapením.
No radeji bych porovnaval "a" a "b", nebo "String(a,1)" a "String(b,1)" - cim min konverzi po ceste, tim vetsi sance, ze se nezanese nejaka nepresnost

Nebo "abs(a-b)<0.001"
To určitě. Nevidím žádný důvod proč bych to dělal jinak.
Jen jsem chtěl tazateli ukázat, že když se použije stejná metoda převodu, tak by rovnost měla platit :mrgreen:

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 12 hostů