Mikor és miért érdemes közönséges törtekkel számolni?

A float típus behatárolt számábrázolási pontosságából adódó gondokra a decimal modul eszközei tudnak bizonyos mértékig megoldást nyújtani, amelyekről az előző bejegyzésekben volt szó.

Azonban a Decimal típus sem tud végtelen pontosságot biztosítani, ami a két egész szám hányadosaként felírható racionális számok esetében akkor zavaró, ha azok végtelen vegyes vagy tiszta szakaszos tizedestörtként írhatók fel. Ebben az esetben különösen hasznos lehet a közönséges törtekkel való számolás. A számlálóval és nevezővel megadható közönséges törtek a szabványos könyvtár fractions moduljának Fraction típusával állíthatók elő.

A végtelen tizedestörtek float típussal való ábrázolása a pontossági kérdéseken felül akár olyan programfutásbeli hibákat, problémákat is okozhatnak, amelyeket nem biztos, hogy mindig könnyű feltárni és javítani. Fraction típusú közönséges törtek használatával az ilyen gondok is olykor egyszerűen orvosolhatók.

Vegyük ennek illusztrálására példaként azt, hogy egy esküvőn egy adott tömegű tortát kell a vendégek létszámának megfelelően egyenlő szeletekre felvágni. A menyasszony előtt tehát kezdetben az érintetlen egész torta áll. Levágja az első szeletet és azt odaadja az egyik vendégnek. Most a megmaradt tortából levágja a következő szeletet és egy másik vendégnek adja. Igy folytatja mindaddig, amíg el nem fogy a torta.

Az ezt modellező függvény definíciója alább látható.

A függvény első argumentumaként a teljes torta össztömegét kell megadni grammban. A második paraméter fogadja a felosztási arányt, ami a vendégek számának a reciproka. A függvénytörzsben addig veszünk le a tortából, amíg az el nem fogy, vagyis a maradék nulla. Mivel tudjuk, hogy float típus esetén nem biztos, hogy egzakt nullát kapunk, így egy ahhoz közeli kis értékre állítjuk a ciklus leállási feltételét. A függvény ellenőrzésképpen az egyes szeletek tömegének összegével, valamint a maradék tortatömeggel tér vissza.

A teszteredményekből láthatjuk, hogy Fraction esetén pontos eredményt kapunk. Azonban, ha a felosztási arányt float típussal adjuk meg, akkor nem. Gondolhatnánk, hogy a pontosság növeléséhez akkor csökkentsük a ciklusleállási feltételben a toleranciaértéket, azaz közelítsük jobban a nullához. Ha ezt tesszük, és 1e-12, vagy még kisebb értékekkel próbálkozunk, és lefuttatjuk a programot, akkor tapasztalhatjuk, hogy végtelen ciklusba kerülünk. Ennek oka, hogy a közbenső kivonások eredménye nem fog egy bizonyos értéknél kisebbet kiadni. Ráadásul ez a minimum érték a kezdeti tortatömegtől függ. Tehát, ha az módosul, akkor olyan toleranciaérték esetén is végtelen ciklusba kerülhetünk, ami korábban működött.

A biztos és pontos megoldást itt tehát a Fraction alkalmazása nyújtja.

A Fraction típusú közönséges törtek használati részleteit és további érdekes alkalmazási lehetőségeit (pl. lánctörtek számítása) a Python tudásépítés lépésről lépésre című e-könyv egy önálló fejezetben ismerteti.

Érdekel a Python tudásépítés lépésről lépésre az alapoktól az első asztali alkalmazásig című e-könyv.