Jak násobit necelým číslem v celočíselné aritmetice ?

V některých případech je třeba přepočítat celočíselnou hodnotu pomocí linerání transformace typu y = kx + q, kde k a q nejsou celá čísla.

envelope Popis problému:

Předpokládejme, že máme k dispozici vstupní hodnotu, která je zaznamenána v celočíselné aritmetice tj. je typu word, int, longword, longint. U této hodnoty potřebujeme provést změnu měřítka nebo přepočet tak, že ji násobíme hodnotou např. 1.67.

icon_question Proč řešit problém celočíselně:

Problém se řeší celočíselně proto, že celočíselná aritmetika je pro použitý procesor aritmetikou nativní a výpočty v této aritmetice probíhají více jak 10x rychleji.

lightbulb Řešení:

Pro řešení v celočíselné aritmetice vyjdeme z  následujícího zápisu čísla 1.67:

1.67 = 167 / 100

Zatímco číslo 1.67 je číslo reálné tj. toto číslo celočíselná aritmetika nezpracovává, tak podíl čísel 167 / 100 obsahuje pouze čísla celá s nimiž celočíselná aritmetika pracuje. Pro přepočet je krom zmíněné úvahy ještě nutné uvážit možnosti přetečení mezivýsledků, protože pro vhodný postup přepočtu je důležité v prvním kroku násobit a teprve ve druhém dělit (v opačném případě tj. při obráceném postupu dochází ke ztrátě přesnosti výsledku). Pro uváděný případ bude tedy zdrojový text vypadat takto:

var word výsledek
var word hodnota
vysledek = word ((longword(hodnota) * 167 + 50) / 100) ; výpočet probíhá v typu longword
; z důvodu zabránění přetečení mezivýsledku a teprve výsledek se uloží po
; po přetypování ve tvaru word, připočítání hodnoty 50 je z důvodu zaokrouhlení
; výsledku

Uvedený příklad je speciálním případem obecné lineární transfomace, která v sobě zahrnuje i posun. Přepokládejme, že je požadována změna měřítka 3.2x a potun o 8.19. Pokud realizujeme obecnou lineární transformaci y = kx + q platí, že jak k tak q musí být uvažovány ve stejném počtu desetinných míst tj. pro náš případ je:

k = 3.2 = 320 / 100, protože požadujeme q = 8.19 = 819 / 100

výsledný výpočet lineární transformace bude vypadat takto:

var word výsledek
var word hodnota
vysledek = word ((longword(hodnota) * 320 + 819 + 50) / 100) ; výpočet probíhá v typu longword
; připočítání hodnoty 50 je z důvodu zaokrouhlení výsledku