Rutina, která nám vypočítá procentuální podíl mezi dvěma 32-bitovými čísly, která mohou reprezentovat čísla LBA sektorů.
Když jsem psal program MAKER, potřeboval jsem nějak zobrazit, kolik procent je z celého disku již naformátováno. Vzhledem k tomu, že se používá LBA číslo sektoru, klasické dělení dvou čísel nepřicházelo v úvahu, protože by to trvalo příliš dlouho. Nechtěl jsem zatěžovat uživatele, že bude koukat jen na dlouhá čísla a bude si to jen představovat.
Zeptal jsem se proto velkého mága Ziloga, který mi naznačil nějaký postup, ale u jeho výkladu jsem nebyl moc moudrý. Nakonec mi celý postup dokonale vyložil Baze, oběma borcům velice děkuji.
Postup výpočtu je poměrně jednoduchý a dává přiměřené výsledky. Má jistou nevýhodu, jeho početní rozsah je od 0% do 200%. Nelze jej tedy použít kdykoliv, ale na danou úlohu je perfektní.
Cílem je zjistit, z jakých menších částí (jejich procent) je hledaná hodnota složena. Například číslo 75 ze 100 je složena z 50 a 25. 100% si rozdělíme tak, že ho budeme dělit dvěma (v assembleru jednoduché). Bude to následující řada:
100, 50, 25, 12.5, 6.25, 3.125, 1.5625, …
A my se budeme snažit spočítat, z jakých těchto částí je naše číslo složeno. Číslo, které máme jako proměnlivou hodnotu, nazveme PARTIAL a číslo, které reprezentuje 100% (a které taky známe) nazveme TOTAL. Hodnotu, kterou chceme vypočítat, nazveme VYSLEDEK a bude mít počáteční hodnotu 0.
Odečteme PARTIAL-TOTAL. Je-li výsledek kladný (tj. PARTIAL se do TOTAL vejde a jeste zbyde) je z něho hodnota složena a VYSLEDEK=VYSLEDEK+100 a pak PARTIAL=zbytek. Pak TOTAL vydělime dvěma (bude 50%) a znova odečítáme, ale k dalšímu výsledku přičítáme jen 50 v dalším kole jen 25 atd. Vždy to číslo, které reprezentuje procentuelní stav čísla TOTAL.
Pokud bude výsledek odečítání záporný, pak z této hodnoty výsledek složený není a výsledku si nevšímáme, ale TOTAL vydělíme dvěma a PARTIAL necháváme být.
Zjišťujeme z jakých dílů čísla TOTAL je číslo PARTIAL složené a VYSLEDEK pak prostě zobrazíme. Čím je cyklů více, tím je výsledek přesnější.
Nyní rutina:
;vstupujici parametry:
;bcde = cislo aktualniho sektoru
;na adrese ENDSEC je cislo maximalni (tedy 100%)
PROCENTO: ld (PARTIAL),de ;uloz si cislo
ld (PARTIAL+2),bc ;do pameti
ld de,(ENDSEC) ;zjisti si
ld bc,(ENDSEC+2) ;cislo maximalni
ld (TOTAL),de ;a to si uloz taky
ld (TOTAL+2),bc
xor a
ld (VYSLEDEK),a ;vynuluj vysledek
ld hl,TABULKA ;ukazatel na tabulku
ld b,7 ;7 hodnot
PROC2: push bc
ld ix,PARTIAL ;ix=cast
ld de,(TOTAL)
ld bc,(TOTAL+2) ;bcde=100%
ld a,(ix+0) ;proved odecteni
sub e ;TOTAL-PARTIAL
ld e,a ;po jednotlivych
ld a,(ix+1) ;bytech
sbc a,d
ld d,a
ld a,(ix+2)
sbc a,c
ld c,a
ld a,(ix+3)
sbc a,b
ld b,a ;pokud je carry, je vysledek zaporny
jr c,PROC1
ld (PARTIAL),de ;pokud je kladny,uloz vysledek
ld (PARTIAL+2),bc ;na priste
ld a,(VYSLEDEK) ;nacti jiz spocetene cislo
add a,(hl) ;a pricti k ni hodnotu z tabulky
ld (VYSLEDEK),a ;a uloz zpet pro dalsi kolo
PROC1: inc hl ;posun se v tabulce
ld ix,TOTAL ;cele cislo vydel dvema
srl (ix+3)
rr (ix+2)
rr (ix+1)
rr (ix+0)
pop bc
djnz PROC2 ;opakuj 7 krat
ret
VYSLEDEK: db 0
TABULKA: db 100,50,25,12,6,3,1 ;tabulka hodnot procent
PARTIAL: dw 0,0 ;cislo, ktere potrebujeme zjistit
TOTAL: dw 0,0 ;hodnota, kterou odecitame
3 komentáre na “Výpočet procent pro 32-bitová čísla”
Je nám líto, ale formulář pro přidávání komentářů je momentálně uzavřen.
Cool!
Po delší době na webu opět něco kapku nového (aspoň pro mne) a zajímavého (aspoň pro mne)…
Ahoj Dexi, jsem rád, že alespoň jednomu člověku moje rutina připadá zajímavá. To mě těší.
Jeste malickost – jde to udelat bez ztraty presnosti – misto odcitani stale puleneho totalu budeme odecitat porad ten samy total, ale dvojnasobit ten zbytek ;>.