Celočíselné dělení se záporným číslem v Pythonu

modulo

Nazdar, mám jeden dotaz, proč je v Pythonu vymyšlená taková blbost jako že je -11 // 2 rovno -6? To je to totální hovadina, když budu já sám dělit celočíselně, tak mi to vyjde -5 a nějaký zbytek. Proč Python nerespektuje matematiku? To se tam nějaký vývojář nudil? Nebo měl nějaký vývojář Pythonu nutkání se odlišit za každou cenu?

Nehejtuji, chci jen vědět, logický důvod, proč je to tak a ne normálně jako všude jinde.


Radek Miček

Re:Celočíselné dělení se záporným číslem v Pythonu
« Odpověď #1 kdy: 27. 07. 2015, 15:48:20 »
Záleží, jak zaokrouhlujete. Například můžete zaokrouhlovat k 0, pak by vyšlo -5, jak říkáte, nebo lze zaokrouhlovat k mínus nekonečnu, pak vyjde -6.

Re:Celočíselné dělení se záporným číslem v Pythonu
« Odpověď #2 kdy: 27. 07. 2015, 15:49:59 »
Protože // je definován jako "floor division"?
Tj. že vydělí a výsledek projede funkcí floor.

Kolemjdoucí

Re:Celočíselné dělení se záporným číslem v Pythonu
« Odpověď #3 kdy: 27. 07. 2015, 16:06:33 »
Proč Python nerespektuje matematiku? To se tam nějaký vývojář nudil? Nebo měl nějaký vývojář Pythonu nutkání se odlišit za každou cenu?

Protože líní tvůrci Pythonu si chtěli zjednodušit život, jednodušší je tohle furt zaokrouhlovat dolů.
Aby fungovalo 11/2=5 a zároveň -11/2=-5, tak se musí operace pro kladný a záporný čitatel zpracovávat odlišně, je tam práce navíc.

Jann

Re:Celočíselné dělení se záporným číslem v Pythonu
« Odpověď #4 kdy: 27. 07. 2015, 16:17:20 »
Nazdar, mám jeden dotaz, proč je v Pythonu vymyšlená taková blbost jako že je -11 // 2 rovno -6? To je to totální hovadina, když budu já sám dělit celočíselně, tak mi to vyjde -5 a nějaký zbytek. Proč Python nerespektuje matematiku? To se tam nějaký vývojář nudil? Nebo měl nějaký vývojář Pythonu nutkání se odlišit za každou cenu?

Nehejtuji, chci jen vědět, logický důvod, proč je to tak a ne normálně jako všude jinde.

Python to má právě implementováno tak, jak je to normálně definované v matematice. Např. v C to je nestandardně, stejně jako je v C nestandardně udělaná mocnina s racionálním exponentem.

Základní problém u nematematiků tkví v nepochopení funkce nazvané "celá část". Že celá část z 5,6 je 5, to obvykle chápou, ale že celá část z –5,6 je –6, s tím má spousta lidí z nějakého nepochopitelného důvodu problém.
Celá část je nejbližší menší celé číslo, pokud argumentem není celé číslo. Jasné jak facka.
Celočíselný podíl je definován jako celá část reálného podílu. Opět jasné jak facka.


modulo

Re:Celočíselné dělení se záporným číslem v Pythonu
« Odpověď #5 kdy: 27. 07. 2015, 16:24:12 »
Tak v tom případě mi celý život na základce a na střední lhali  :'(

Ok, máte pravdu, opravdu jsem byl přesvědčený, že celočíselné dělení je podle mého způsobu jen to správné, nechápu tedy, proč to blbě učí i ve škole. No nic, člověk pořád něco nového zjišťuje.

Snow

Re:Celočíselné dělení se záporným číslem v Pythonu
« Odpověď #6 kdy: 27. 07. 2015, 16:51:59 »
protože // zaokrouhluje?
Jestli nechceš zaokrouhlovat použij  / (-11 / 2)

Kolemjdoucí

Re:Celočíselné dělení se záporným číslem v Pythonu
« Odpověď #7 kdy: 27. 07. 2015, 17:00:20 »
Základní problém u nematematiků tkví v nepochopení funkce nazvané "celá část". Že celá část z 5,6 je 5, to obvykle chápou, ale že celá část z –5,6 je –6, s tím má spousta lidí z nějakého nepochopitelného důvodu problém.

Základní problém tkví v nepochopení, že funkce celá část je definována jinak pro nezáporné hodnoty a jinak pro záporné.
Mimo to existují operace Floor a Ceil, které se obě chovají jinak než operace Celá část.

Jann

Re:Celočíselné dělení se záporným číslem v Pythonu
« Odpověď #8 kdy: 27. 07. 2015, 17:09:04 »
Základní problém u nematematiků tkví v nepochopení funkce nazvané "celá část". Že celá část z 5,6 je 5, to obvykle chápou, ale že celá část z –5,6 je –6, s tím má spousta lidí z nějakého nepochopitelného důvodu problém.

Základní problém tkví v nepochopení, že funkce celá část je definována jinak pro nezáporné hodnoty a jinak pro záporné.
Mimo to existují operace Floor a Ceil, které se obě chovají jinak než operace Celá část.

Ne. Funkce "celá část" je definována pro všechna reálná čísla stejně a jde o synonymum pro funkci nazvanou "dolní celá část reálného čísla".

Místo psaní nesmyslů do diskusí ti (opět) doporučuji nejdřív si danou věc nastudovat.

Kolemjdoucí

Re:Celočíselné dělení se záporným číslem v Pythonu
« Odpověď #9 kdy: 27. 07. 2015, 17:12:24 »
Ne. Funkce "celá část" je definována pro všechna reálná čísla stejně a jde o synonymum pro funkci nazvanou "dolní celá část reálného čísla".

To je fatální omyl. Výsledek operace -11/2 je -5 zbytek -1. Jestliže máte nějaký jiný názor tak ho mít můžete, ale já s Vámi čas ztrácet nebudu.

JSH

Re:Celočíselné dělení se záporným číslem v Pythonu
« Odpověď #10 kdy: 27. 07. 2015, 17:45:33 »
Matematicky musí celočíselné dělení splňovat n=q*d + r (q = n/d, r = n 'mod' d). Pro kladná čísla je to jednoznačné, ale pro záporná jsou tří možnosti :
  • r je vždycky kladný - eulerův algoritmus
  • r má znaménko dělence - obvyklé v HW
  • r má znaménko dělitele
Ani jedna z možností není "správně". Každá se hodí někdy jindy. Pro zajímavost C třeba vůbec nedefinuje, která možnost se má použít.

frk

Re:Celočíselné dělení se záporným číslem v Pythonu
« Odpověď #11 kdy: 27. 07. 2015, 17:53:04 »
ostrý honza má pravdu, v dokumentaci se dočteš, že operátor // je funkce operator.floordiv .

to dělaní bych dělal: int(round(a/b))

mxlbzn

[OT] Re:Celočíselné dělení se záporným číslem v Pythonu
« Odpověď #12 kdy: 27. 07. 2015, 18:04:48 »
Pan modulo tedy řeší celočíselné dělení, ale s modulo záporného čísla, např. -11 % 10 == 9, je už psychicky srovnán? :)

ivoszz

Re:Celočíselné dělení se záporným číslem v Pythonu
« Odpověď #13 kdy: 27. 07. 2015, 18:05:46 »
Ne. Funkce "celá část" je definována pro všechna reálná čísla stejně a jde o synonymum pro funkci nazvanou "dolní celá část reálného čísla".

To je fatální omyl. Výsledek operace -11/2 je -5 zbytek -1. Jestliže máte nějaký jiný názor tak ho mít můžete, ale já s Vámi čas ztrácet nebudu.

Možná nebudete ztrácet čas, ale to neznamená, že fatální omyl tady nepropagujete vy. Protože zbytek je definován jako číslo větší nebo rovno nule a menší než dělitel, je výsledkem -6 a zbytek 1. Pokud vás někdo učil něco jiného, běžte mu vynadat. :)

Jann

Re:Celočíselné dělení se záporným číslem v Pythonu
« Odpověď #14 kdy: 27. 07. 2015, 18:16:19 »
ostrý honza má pravdu, v dokumentaci se dočteš, že operátor // je funkce operator.floordiv .

to dělaní bych dělal: int(round(a/b))

V tom případě si musím nasypat popel na hlavu, Python tak neznám. Floored division není totéž, co standardní v matematice definované celočíselné dělení, tj. eukleidovské dělení. Floored division, někdy také "knuthovské dělení", zachovává u zbytku znaménko dělitele. IEEE 754 zase specifikuje, že podíl a zbytek se zvolí tak, aby byl zbytek v absolutní hodnotě co nejmenší. Atd. Celý tenhle chaos vznikl historicky kvůli různé implementaci a representaci čísel v HW a každá z těch nestandardních definic trpí oproti té eukleidovské "ortogonální" nějakým problémem.

To vše ale nic nemění na faktu, že základní v matematice používanou definicí celočíselného dělení a jeho zbytku je definice podle Eukleida, tj. zbytek vždy nezáporný a menší než absolutní hodnota dělitele.