Ti, ktori listuju BASIC nielen pomocou prikazu LIST ale aj
nejakym monitorom, sa uz urcte stretli so systemom kodovania
vsetkych ciselnych hodnot. Prave pre tych je urceny nasledujuci
program.
Vsetky cisla su kodovane do 5 bajtov. Pokial je to cele cislo v
rozsahu -65535 az 65535, nie je ziadny problem ho precitat.
Prvy bajt vyjadruje znamienko (0:+, 255:-), druhy je nulovy, treti je
nizsi bajt tohto cisla a stvrty je vyssi bajt. Na poslednom
piatom bajte nezalezi, ale pre prehladnost sa tam zvykne davat
nula. Vdaka takemuto usporiadaniu nie je problem toto cislo
precitat z lubovolneho monitora.
Ale co ak je to cislo v plavajucej desatinnej ciarke ? Z pameti
na vas hladi pet vseobecnych bajtov a vy v okamihu neviete, ci
mate pocitac resetnut alebo ho radsej rovno vytiahnut z prudu.
No, az take hrozne to zase nie je, lebo sa tu ponukaju hned dve
skupiny moznosti ako toto cislo zistit. Podla prvej skupiny
(nazvime ju "Analyticke sposoby") sa vypocita hodnota cisla
podla nasledujuceho postupu:
Toto je sice pekny sposob, ale uprimne: chcelo by sa vam to zakazdym pocitat ? Dalo by sa to urobit na programovatelnej kalkulacke, ale ani to nie je velka vyhra, lebo aj na tej najprogramovatelnejsej kalkulacke by ste museli do nej klepat tych 5 bajtov. Navyse kalkulacky maju obvykle inu presnost vypoctu a preto by sa mohla vypocitana hodnota lisit od skutocnej. Istym riesenim by bolo tento vypocet naprogramovat do basicu, napriklad takto:
LET c=2*(.5+PEEK (add+1)/256 + PEEK (add+2)/65536 + PEEK (add+3)/16777216 + PEEK (add+4)/4.2949673e9) * 2^(PEEK add-129)
Tento sposob je pouzity aj v programe Rexo. Avsak nesie zo sebou jeden obrovsky hacik. Pre cisla bliziace sa maximalnej zobrazitelnej hodnote 1.7014118*10^38 tento vyraz fungovat nebude, pretoze medzivysledky vypoctu vyssie spomenuteho vyrazu mozu presiahut spomenutu maximalnu hodnotu. Tento vyraz by sa dal upravit tak, aby to nenastalo, ale to by so sebou prinieslo trochu nizsiu presnost vypoctu.
Druhu skupinu moznosti nazvime "Zdravy sedliacky rozum".
Vychadzajme z toho, ze basic si vie poradit s tymito piatimi
bajtami. No a tychto nasich 5 bajtov mu proste "podstrcime".
Najjednoduchsie sa to urobi tak, ze do prveho riadku v basicu
napiseme PRINT 0 (vtedy si on v pameti vyhradi pet bajtov, kam
hned ulozi hodnotu tej nuly) a potom mu do tychto piatich bajtov
napokujeme nasich pet bajtov. Nakoniec basic spustime a prikaz
PRINT nam vypise nasu tuzobne ocakavanu hodnotu.
Funguje to preto, lebo ked bezi basicovy program, ako hodnoty cisel sa
neberu tie, co vidno pri listingu ale tie, ktore su definovane piatimi
bajtami v pameti (toto sa velmi casto zneuziva vo vseliakych
ochranach). Adresa basicu je za normalnych okolnosti na 23755 a
tych pet bajtov je o sedem bajtov dalej po kode 14.
Avsak aj toto bol dost pracny sposob. Musite zasahovat do basicoveho programu (co je nie vzdy mozne) a pokovat tych pet bajtov. Nasledujuci program vsetky tieto nevyhody odstranuje. Ma len 7 bajtov, takze ani nebude problem si ho rucne napokovat.
E1 pop hl 2A 76 5C ld hl,(#5c76) C3 B4 33 jp #33b4
V dekadickom tvare: 225, 42, 118, 92, 195, 180, 51.
Ked budete mat tento program v pocitaci, spravte RANDOMIZE X,
kde X je adresa vasich piatich bajtov a potom PRINT USR Y,
kde Y je zaciatocna adresa tohto programu. A vypise sa vam vasa
tuzobne ocakavana hodnota cisla.
Na tomto mieste asi mnohi namietnu, ze funkcia USR predsa
vracia obsah registra BC (t.j. cele cislo 0-65535) a teda nemoze
vratit lubovolne realne s plavajucou desatinnou ciarkou ! Tak
pre tych iba tolko: Niekedy sa deju aj zazraky a dalej bude
vysvetlene, ako je to mozne.
Ak by ste sa nahodou chceli pozriet, ake cislo sa nachadza na
adrese 0, tak namiesto RANDOMIZE 0 spravte POKE 23760,0: POKE
23761,0 (to preto, lebo RANDOMIZE pri nulovom alebo ziadnom
argumente berie nahodne cislo z premennej FRAMES).
Ako tento program pracuje ? Hned na zaciatku vidite POP HL.
Dost neobvykly zaciatok, poviete si. Ale tento program vyuziva
istu fintu so zasobnikom. Totiz pri volani USR prva navratova
adresa na zasobniku procesora ukazuje na rutinku #2D2B,
ktora uklada hodnotu registra BC na zasobnik kalkulacky vo forme
piatich bajtov. A prave tato rutinka je teraz pre nas neziaduca,
preto je jej adresa zlikvidovana pomocou toho POPu.
Lenze pri navrate z USR by sa patrilo nieco dat na zasobnik
kalkulacky. A preco by sme tam nedali tych nasich pet bajtov, o
ktore nam prave ide ? A prave ina rutinka na adrese #33B4 robi
takuto cinnost. Takze ju uz len staci zavolat s tym ze v
registri HL je adresa odkial sa ma zobrat tychto pet bajtov.
Register HL sa naplna hodnotou ulozenou na adrese 23670.
Je to premenna SEED, ktora sa nastavuje pomocou prikazu
0RANDOMIZE.
Samozrejme by sa dalo v nasom programe namiesto LD HL,(23670)
napisat LD HL,XXX a hodnotu XXX priamo pokovat, ale
sposob s vyuzitim RANDOMIZE sa mi vidi predsa len praktickejsi.
Verim, ze ak vas tento program nezaujal tym ze zistuje hodnoty
cisel, aspon vam priniesol nieco nove v tom, ako zariadit aby
funkcia USR vracala lubovolnu realnu hodnotu.
Vas Busy.