sobota 22. července 1995

Ako na čísla v plávajúcej desatinnej čiarke?

autor: Busy

Ti, ktorí listuju BASIC nielen pomocou příkazů LIST, ale aj nějakým monitorom, sa už určitě stretli so systémom kódovania všetkých číselných hodnot. Právě pre tých je určeny nasledujúci program.
Všetky čísla sú kódované do 5 bajtov. Pokial je to celé číslo v rozsahu -65535 až 65535, nie je žiadny problém ho přečítat. Prvý bajt vyjadřuje znamienko (0:+, 255:-), druhý je nulový, třetí je nižší bajt tohto čísla a štvrtý je vyšší bajt. Na poslednom piatom bajte nezáleží, ale pře prehladnost sa tam zvykne dávat nula. Vďaka takémuto usporiadaniu nie je problém toto číslo přečítat z lubovolneho monitora.


Ale co ak je to číslo v plavajucej desatinnej ciarke? Z paměti na vás hladí pět všeobecných bajtov a vy v okamihu neviete, či máte počítač resetnut alebo ho radšej rovno vytiahnuť z prúdu. No, až také hrozně to zase nie je, lebo sa tu ponúkajú hned dvě skupiny možnosti ako toto číslo zistiť. Podlá prvej skupiny (nazvime ju "Analytické sposoby") sa vypočítá hodnota čísla podlá nasledujúceho postupu:

Nech Bi je hodnota i-tého bajtů. (i=1..5) Znamienko čísla je podlá 7. bitů druhého bajtů (0:+,1:-). 7. bit B2 teraz nastavme na 1 (to je ten znamienkovy). Potom hodnota nášho čísla bude: 2^(B1-128) * (B2/(2^8) + B3/(2^16) + B4/(2^24) + B5/(2^32))

Toto je sice pěkný sposob, ale upřímně: chcelo by sa vám to zakazdym počítat? Dalo by sa to urobit na programovatelnej kalkulacke, ale ani to nie je velká výhra, lebo aj na tej najprogramovatelnejsej kalkulacke by stě museli do něj klepat tých 5 bajtov. Navýše kalkulačky májů obvykle inu přesnost výpočtu a preto by sa mohla vypočítána hodnota lišit od skutočnej.

Druhů skupinu možnosti nazvime "Zdravý sedliacky rozum". Vychadzajme z toho, že basic si vie poradit s týmito piatimi bajtami. No a týchto našich 5 bajtov mu prostě "podstrčíme". Najjednoduchsie sa to urobí tak, že do prvého riadku v basicu napíšeme PRINT 0 (vtedy si on v paměti vyhradí pět bajtov, kam hned uloží hodnotu tej nuly) a potom mu do týchto piatich bajtov napokujeme našich pět bajtov. Nakoniec basic spustíme a příkaz PRINT nám vypíše našu tuzobne ocakavanu hodnotu.


Totiž keď běží basicovy program, ako hodnoty čísel sa neberu tie, co vidno při listingů ale tie, ktoré sú definované piatimi bajtami v paměti (toto sa velmi často zneužívá vo všeliakých ochranách). Adresa basicu je za normálnych okolností na 23755 a tých pět bajtov je o šedém bajtov ďalej po kóde 14.
Avšak aj toto bol dost pracný sposob. Musíte zasahovat do basicoveho programu (co je nie vždy možné) a pokovat tých pět bajtov. Nasledujúci program všetky tieto nevýhody odstraňuje. Má len 7 bajtov, takže ani nebude problém si ho ručně napokovat.


Tu je:
E1   pop hl
  2A 76 5C ld hl,(#5c76)
  C3 B4 33 jp #33b4

V dekadickom tvare: 225,42,118,92,195,180,51. Keď budete mat tento program v počítači, spravte RANDOMIZE X, kde X je adresa vašich piatich bajtov a potom PRINT USR Y, kde Y je zaciatocna adresa tohto programu. No a vypíše sa vám vaša tuzobne očakávaná hodnota čísla.


Na tomto mieste asi mnohí namietnu, že funkcia USR predsa vracia obsah registra BC (t.j. celé číslo 0-65535) a teda nemože vrátit lubovolne reálné s plavajucou desatinnou ciarkou! Tak pře tých iba tolko: Niekedy sa dějů aj zázraky a ďalej bude vysvětlené, ako je to možné.


Ako tento program pracuje? Hned na začiatku vidíte POP HL. Dost neobvyklý začiatok, poviete si. Ale tento program využívá istú fintu so zasobnikom. Totiž při volání USR prvá návratová adresa na zásobníku procesora ukazuje na rutinku (adresa #2d2b), ktorá ukládá hodnotu registra BC na zásobník kalkulačky vo formě piatich bajtov. A právě tato rutinka je teraz pře nás neziaduca, preto je jej adresa zlikvidována pomocou toho POPu.
Lenze při návrate z USR by sa patřilo niečo dat na zásobník kalkulačky. A prečo by smě tam nedali tých našich pět bajtov, o ktoré nám právě ide? A právě ina rutinka na adrese #33b4 robí takúto činnost. Takže ju už len stačí zavolat s tým že v registri HL je adresa odkial sa má zobrať týchto pět bajtov.
Register HL sa naplna hodnotou uloženou na adrese 23670. Je to přeměnná SEED, ktorá sa nastavuje pomocou příkazů RANDOMIZE. Samozřejmě by sa dalo v našom programe namiesto LD HL,(23670) napísať LD HL,XXX a hodnotu XXX priamo pokovat, ale sposob s využitím RANDOMIZE sa mi vidí predsa len praktickejsi.

Věřím, že ak vás tento program nezaujal tým že zisťuje hodnoty čísel, aspoň vám priniesol niečo nové v tom, ako zariadiť aby funkcia USR vracala lubovolnu reálnu hodnotu.

Diakritika doplněna programem CSDIAK.

Žádné komentáře:

Okomentovat