Python zaokruhlovanie na cele cislo nefunguje spravne

Python zaokruhlovanie na cele cislo nefunguje spravne
« kdy: 18. 02. 2021, 12:30:00 »
Tak dalsia otazka.
Ako je mozne ze Python "Nevie spravne zaokruhlovat" ma cele cislo?
Kód: [Vybrat]
data_1 = 83.5
data = 82.5
print(round(data_1))
print(round(data))
Vysledok
Kód: [Vybrat]
84
82
ako to osetrit aby to vzdy zaokruhlovalo hore?


Re:Python zaokruhlovanie na cele cislo nefunguje spravne
« Odpověď #1 kdy: 18. 02. 2021, 12:38:32 »
Mozna to chce cist dokumentaci, z https://docs.python.org/3/library/functions.html#round:
Citace
For the built-in types supporting round(), values are rounded to the closest multiple of 10 to the power minus ndigits; if two multiples are equally close, rounding is done toward the even choice (so, for example, both round(0.5) and round(-0.5) are 0, and round(1.5) is 2).

Pokud chces standardnejsi chovani, zkus
Kód: [Vybrat]
num_rounded = int(num + 0.5)

Re:Python zaokruhlovanie na cele cislo nefunguje spravne
« Odpověď #2 kdy: 18. 02. 2021, 13:32:17 »
Možná by stálo za to napsat, o jaký python se jedná.

Kód: [Vybrat]
Python 2.7.15 (default, Oct 15 2018, 15:24:06)
[GCC 8.1.1 20180712 (Red Hat 8.1.1-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> data_1 = 83.5
>>> data = 82.5
>>> print(round(data_1))
84.0
>>> print(round(data))
83.0

RDa

  • *****
  • 1 254
    • Zobrazit profil
    • E-mail
Re:Python zaokruhlovanie na cele cislo nefunguje spravne
« Odpověď #3 kdy: 18. 02. 2021, 14:01:12 »
Zaokrouhlovani sudym smerem je jedno ze standardnich chovani pro IEEE floaty:
https://en.wikipedia.org/wiki/Rounding#Round_half_to_even



Pajaha

  • ***
  • 141
    • Zobrazit profil
    • E-mail
Re:Python zaokruhlovanie na cele cislo nefunguje spravne
« Odpověď #5 kdy: 19. 02. 2021, 16:38:29 »
Kterého dementa napadlo, že zaokrouhlených 1.5 se bude rovnat zaokrouhlených 2.5 ?
By mě zajímalo, kdo vymýšlí takovéhle vyfikundace a navíc je nacpe do standardní funkce.
K čemu to vůbec je?
 


Re:Python zaokruhlovanie na cele cislo nefunguje spravne
« Odpověď #6 kdy: 19. 02. 2021, 17:10:47 »
Kterého dementa napadlo, že zaokrouhlených 1.5 se bude rovnat zaokrouhlených 2.5 ?
By mě zajímalo, kdo vymýšlí takovéhle vyfikundace a navíc je nacpe do standardní funkce.
K čemu to vůbec je?
Napadlo to někoho, kdo toho o zaokrouhlování ví víc, než vy. Existuje totiž mnoho způsobů, jak zaokrouhlovat. Tenhle způsob zaokrouhlování vede k menší průměrné chybě, která se zaokrouhlováním vnáší. Ona je totiž pětka jaksi přesně uprostřed intervalu, takže když ji budete zaokrouhlovat stále k větší absolutní hodnotě (tzv. matematické zaokrouhlování, které asi znáte ze ZŠ) a budete mít nerovnoměrně rozložená kladná a záporná čísla (např. budete zaokrouhlovat jenom samé kladné hodnoty), bude vám zaokrouhlování systematicky posouvat výsledek (u kladných čísel nahoru).

Nazývat někoho dementem jenom kvůli vlastní neznalosti je – řekněme hloupé.

Mlocik97

  • *****
  • 520
  • In love with Linux
    • Zobrazit profil
    • E-mail
Re:Python zaokruhlovanie na cele cislo nefunguje spravne
« Odpověď #7 kdy: 19. 02. 2021, 18:04:07 »
Kterého dementa napadlo, že zaokrouhlených 1.5 se bude rovnat zaokrouhlených 2.5 ?
By mě zajímalo, kdo vymýšlí takovéhle vyfikundace a navíc je nacpe do standardní funkce.
K čemu to vůbec je?
Napadlo to někoho, kdo toho o zaokrouhlování ví víc, než vy. Existuje totiž mnoho způsobů, jak zaokrouhlovat. Tenhle způsob zaokrouhlování vede k menší průměrné chybě, která se zaokrouhlováním vnáší. Ona je totiž pětka jaksi přesně uprostřed intervalu, takže když ji budete zaokrouhlovat stále k větší absolutní hodnotě (tzv. matematické zaokrouhlování, které asi znáte ze ZŠ) a budete mít nerovnoměrně rozložená kladná a záporná čísla (např. budete zaokrouhlovat jenom samé kladné hodnoty), bude vám zaokrouhlování systematicky posouvat výsledek (u kladných čísel nahoru).

Nazývat někoho dementem jenom kvůli vlastní neznalosti je – řekněme hloupé.

To mi príde sprosté, a na výpočet priemernej hodnoty po zaokrúhlení čísel z pola desatinných čísel (napr. všetkých končiacich .5) existuje logickejší spôsob pomocou sčitovania zvyškov z modula a deleno a následne je zdeliť a pričítať ku priemeru samotných celých čísel (s odrezaním desatinej časti), alebo ešte lepší, a to vynásobiť hodnoty *10 následne vypočítať priemer a výsledný priemer vydeliť /10 a previesť na celé číslo. V oboch prípadoch neprekročíš odchýlku väčšiu než 0.5
« Poslední změna: 19. 02. 2021, 18:07:10 od Mlocik97 »

Logik

  • *****
  • 876
    • Zobrazit profil
    • E-mail
Re:Python zaokruhlovanie na cele cislo nefunguje spravne
« Odpověď #8 kdy: 19. 02. 2021, 18:49:05 »
Mlocik:To ale zacházíš se znalostí původních nezaokrouhlenejch čísel. Todle řeší problém, když nejdřív zaokrouhlíš, a pak Tě napadne spočítat průměr. Tam už nijak nevyřešíš, že průměr čísel 0.5,1.5 Ti vyjde 1.5, protože dostaneš čísla 1,2 a z nich nijak nevyčteš, co byly původně.
Zatímco  u velkých sad čísel (pokud tedy nemají nějaké obskurní rozdělení), když to zaokrouhlíš tím IEEE způsobem, tak se Ti chyba "požere"  s poměrně velkou statistickou jistotou.

PS: A úplně nejlepší je takovej průměr znova zaokrouhlit. Vyjde Ti, že průměr čísel 0.5 a 1.5 je 2....

Re:Python zaokruhlovanie na cele cislo nefunguje spravne
« Odpověď #9 kdy: 19. 02. 2021, 19:11:27 »
To mi príde sprosté, a na výpočet priemernej hodnoty po zaokrúhlení čísel z pola desatinných čísel (napr. všetkých končiacich .5) existuje logickejší spôsob pomocou sčitovania zvyškov z modula a deleno a následne je zdeliť a pričítať ku priemeru samotných celých čísel (s odrezaním desatinej časti), alebo ešte lepší, a to vynásobiť hodnoty *10 následne vypočítať priemer a výsledný priemer vydeliť /10 a previesť na celé číslo. V oboch prípadoch neprekročíš odchýlku väčšiu než 0.5
Ono samozřejmě nejde o výpočet průměrné hodnoty zaokrouhlených čísel. Představte si, že vám třeba banka vyplácí úroky ze zůstatku na účtu. Na účtu typicky nemáte nějakou kulatou částku, takže po vypočtení úroku vyjde nějaké hausnumero jako 0,12489 Kč. To vám banka samozřejmě vyplatit nemůže, je potřeba to zaokrouhlit na halíře. No a když to banka bude zaokrouhlovat matematicky, tedy 0,5 hal vždy nahoru, zaplatí nakonec na úrocích víc, než by odpovídalo úrokové sazbě. Když bude zaokrouhlovat na nejbližší sudé číslo, vyplatí celkově přibližně tolik, kolik by odpovídalo úrokové sazbě – zaokrouhlovací chyby se navzájem víceméně vyruší.

_Jenda

  • *****
  • 670
    • Zobrazit profil
    • https://jenda.hrach.eu/
    • E-mail
Re:Python zaokruhlovanie na cele cislo nefunguje spravne
« Odpověď #10 kdy: 19. 02. 2021, 19:13:17 »
To mi príde sprosté, a na výpočet priemernej hodnoty po zaokrúhlení čísel z pola desatinných čísel (napr. všetkých končiacich .5) existuje logickejší spôsob
To byl příklad. Existuje hromada dalších numerických algoritmů a určitě to nechceš řešit u každého individuálně, pokud to vůbec jde. Právě proto se zavedlo zaokrouhlování, které pokud možno nevnáší systematickou chybu.

alebo ešte lepší, a to vynásobiť hodnoty *10 následne vypočítať priemer a výsledný priemer vydeliť /10 a previesť na celé číslo
Jak se to bude chovat, pokud 10násobek (resp. 2násobek pokud to počítáš normálně binárně) po uložení do floatu ztratí přesnost? Ne, udělat numerické algoritmy dobře je věda, a bohužel to náhodný diskutující z Rootu bez ani základní znalosti problémů, které ho můžou potkat, neobejde…

Re:Python zaokruhlovanie na cele cislo nefunguje spravne
« Odpověď #11 kdy: 19. 02. 2021, 19:41:21 »
už se těším, až tu více lidí přijde na to, že 0.1 s 20 desetiními místy u float je 0.999xxx :)

Kit

  • *****
  • 575
    • Zobrazit profil
    • E-mail
Re:Python zaokruhlovanie na cele cislo nefunguje spravne
« Odpověď #12 kdy: 19. 02. 2021, 19:54:31 »
už se těším, až tu více lidí přijde na to, že 0.1 s 20 desetiními místy u float je 0.999xxx :)

Není...

Re:Python zaokruhlovanie na cele cislo nefunguje spravne
« Odpověď #13 kdy: 19. 02. 2021, 19:56:22 »
už se těším, až tu více lidí přijde na to, že 0.1 s 20 desetiními místy u float je 0.999xxx :)
„Číslo s X desetinnými místy u float“ je nesmysl, pokud tedy myslíte float podle IEEE 754 (tedy ve skutečnosti single – 32 bitů). Každé číslo reprezentovatelné v IEEE 754 je reprezentované právě jedním způsobem. Pokud si určíte počet desetinných míst na výstupu, bude se muset buď zaokrouhlit nebo doplnit nulami (pokud zrovna nepotřebujete ten počet míst, který je v daném čísle použit). Takže když se pokusíte do single typu uložit 0,1, uloží se tam ve skutečnosti přesně 0,100000001490116119384765625. Pokud z toho při výpisu dostanete 0,999…, máte něco špatně…

Mlocik97

  • *****
  • 520
  • In love with Linux
    • Zobrazit profil
    • E-mail
Re:Python zaokruhlovanie na cele cislo nefunguje spravne
« Odpověď #14 kdy: 19. 02. 2021, 20:32:43 »
To mi príde sprosté, a na výpočet priemernej hodnoty po zaokrúhlení čísel z pola desatinných čísel (napr. všetkých končiacich .5) existuje logickejší spôsob pomocou sčitovania zvyškov z modula a deleno a následne je zdeliť a pričítať ku priemeru samotných celých čísel (s odrezaním desatinej časti), alebo ešte lepší, a to vynásobiť hodnoty *10 následne vypočítať priemer a výsledný priemer vydeliť /10 a previesť na celé číslo. V oboch prípadoch neprekročíš odchýlku väčšiu než 0.5
Ono samozřejmě nejde o výpočet průměrné hodnoty zaokrouhlených čísel. Představte si, že vám třeba banka vyplácí úroky ze zůstatku na účtu. Na účtu typicky nemáte nějakou kulatou částku, takže po vypočtení úroku vyjde nějaké hausnumero jako 0,12489 Kč. To vám banka samozřejmě vyplatit nemůže, je potřeba to zaokrouhlit na halíře. No a když to banka bude zaokrouhlovat matematicky, tedy 0,5 hal vždy nahoru, zaplatí nakonec na úrocích víc, než by odpovídalo úrokové sazbě. Když bude zaokrouhlovat na nejbližší sudé číslo, vyplatí celkově přibližně tolik, kolik by odpovídalo úrokové sazbě – zaokrouhlovací chyby se navzájem víceméně vyruší.

V takej situácii nie je normálne v systéme ukladať hodnotu s vysokou presnosťou (trebárs aj 10 desatinných miest), ale pri vyplatený "odrezať tých 0.00neco a čakať až sa pri ďalšom zapísaní úroky preklopý tá hodnota cez 0.01 ? takto nikdy nestratí ani cent ani nedá ani cent navyše. Že v systéme bude hodnota desatinná nemusí znamenať že musí banka vyplatiť desatinné haliere.