Obsah / Utility / TEXTFORM / FltToTextBufN
Zdrojový kód: INCLUDE\UTIL\TEXTFORM.INC, UTIL\TEXTFORM.ASM
Související:
FltToTextBuf | Zformátování desetinného čísla do bufferu | |
MixToTextBufN | Délka textu formátovaného smíšeného desetinného čísla | |
FormToTextBufN | Délka formátovaného textu |
FltToTextBufN - Délka textu formátovaného desetinného čísla
Funkce FltToTextBufN zjistí délku formátovaného desetinného čísla v bufferu.
|
Na vstupu funkce obsahuje registr ST0 desetinné číslo ke konverzi a registr EBX formátovací parametry FORMPAR (ne ukazatel). Na výstupu je navrácena v registru EAX délka textu. Funkce používá 1 další registr koprocesoru. Vstupní číslo v registru ST0 zůstává zachováno, neuvolňuje se ze zásobníku koprocesoru. K uvolnění čísla z registru ST0 lze použít instrukci "ffreep st0" volanou po ukončení funkce. Funkce předpokládá, že koprocesor je v implicitním nastavení - přesnost 64 bitů, zaokrouhlení k nejbližšímu.
|
Po úschově obsahu registrů je v zásobníku vytvořeno volné místo pro uložení čísla v rozšířené přesnosti a formátovací parametry jsou uloženy do proměnné FLTNForm.
|
Číslo se uloží do bufferu v zásobníku (nejdříve se musí zduplikovat, protože není k dispozici instrukce pro uložení čísla v rozšířené přesnosti bez uvolnění čísla ze zásobníku koprocesoru). Do registru EDX se načte exponent čísla. Příznak záporného čísla (bit 15 exponentu) se uloží do proměnné FLTNSign. Číslo se převede na absolutní hodnotu. Vynulováním nejvyššího bitu v registru DX se vynuluje znaménkový bit. Je-li exponent v registru DX nulový, jedná se o speciální případ nuly nebo nenormalizovaného čísla.
|
V případě nulového exponentu se provede text mantisy. Není-li mantisa nulová, jedná se o nenormalizované číslo (s exponentem menším než přibližně 1e-4931), takové číslo se bude dále zpracovávat běžným způsobem.
Jsou-li exponent i mantisa nulové, jedná se o nulu. Číslo se uvolní z registru koprocesoru a dále se pokračuje obsluhou se zkrácením koncových nul nebo bez zkrácení nul.
|
Má-li exponent v registru DX hodnotu 7FFFh, jedná se o další zvláštní případ - nekonečno nebo nedefinované číslo. Číslo se uvolní ze zásobníku a do registru ECX se připraví délka textu (=7), funkce poté přejde přímo na obsluhu minimální šířky pole s textem.
|
Pomocí funkce FloatSplit je číslo rozloženo na mantisu a dekadický exponent. Na vstupu funkce je v registru EDX binární exponent čísla, registr ECX ukazuje na buffer čísla v zásobníku a v registru ST0 je absolutní hodnota konvertovaného čísla. Funkce navrací v registru EBX dekadický exponent a v registru ST0 mantisu čísla (normalizovanou do rozsahu 1 včetně až 10 vyjma).
|
Číslo bude pomocí funkce FloatMantBCD zaokrouhleno na poslední číslici a rozloženo na jednotlivé číslice. Před voláním funkce je do registru EAX připravena požadovaná přesnost.
Není-li nastaven příznak FORMFLAG2_Prec, má přesnost význam počtu číslic desetinné části. Přičtením exponentu se obdrží počet zobrazených platných číslic - 1. Podteče-li počet číslic pod 0, číslo leží celé za koncem zobrazené desetinné části, počet číslic se omezí na 0.
Je-li zvolena alternativní přesnost FORMFLAG2_Prec, má přesnost význam počtu významných číslic. Odečtením 1 se provede korekce pro funkci FloatMantBCD (která očekává počet číslic bez první číslice), došlo-li podtečení pod 0, omezí se počet číslic na 0.
Do registru ECX se připraví ukazatel na buffer čísla v zásobníku. Testem příznaku FORMTYPE_Cap_b je funkci předán příznak, zda se má vypnout zaokrouhlování poslední zobrazené číslice. Voláním FloatMantBCD se mantisa převede na BCD číslice.
|
Bude následovat ořezání nevýznamných koncových nul (s využitím funkce FloatTrunc). Do registru EDX se připraví ukazatel na poslední bajt mantisy v BCD tvaru a rozliší se, jakým způsobem má být interpretována požadovaná přesnost.
Je-li nastaven příznakový bit FORMFLAG2_Prec, má přesnost význam počtu významných číslic. Přesnost navrácená funkcí FloatTrunc (tedy počet významných číslic - 1) se použije jako nová požadovaná přesnost k zápisu čísla, tj. počet dekódovaných významných číslic - 1. Odečtením exponentu v registru EBX se obdrží počet číslic desetinné části. Ponechá se v registru ECX a při podtečení pod nulu (tj. číslo je příliš vlevo) se omezí na 0.
Není-li příznakový bit FORMFLAG2_Prec nastaven, má přesnost význam počtu desetinných míst. Není-li požadováno odstranění nevýznamných koncových nul, následující úsek se přeskočí. Jinak se pokračuje přípravou požadované přesnosti do registru EAX. Přičtením exponentu z registru EBX se zjistí vzdálenost první významné číslice od poslední číslice desetinné části. Podteče-li vzdálenost pod nulu, leží číslo za koncem desetinné části a tedy se nezobrazí. V tom případě se nahradí číslem nula bez desetinných míst.
Zavoláním funkce FloatTrunc se zjistí počet významných číslic - 1 (registr ECX). Odečtením exponentu z registru EBX se obdrží skutečný počet číslic desetinné části. V případě podtečení, tj. leží-li číslo příliš vlevo, se omezí na nulu. Do registru EAX se načte požadovaná přesnost a porovná se se skutečnou přesností. Je-li skutečná přesnost nižší, nahradí se jí požadovaná přesnost v proměnné formátovacích parametrů.
|
V další části bude zjištěna délka textu dekódovaného čísla. Do registru ECX se připraví požadovaná přesnost představující počet číslic za desetinnou tečkou. V případě alternativní přesnosti se tato instrukce přeskočí s registrem ECX již připraveným.
Do registru AL se připraví znaménkový bit, do registru AH formátovací příznaky. Je-li znaménkový bit nastaven (bude znaménko "-") nebo je-li nastaven požadavek vynuceného znaménka (bude znaménko "+") nebo je-li nastaven požadavek vynucené mezery, připraví se do registru EAX číslo 1 jako délka textu znaménka, jinak bude obsah registru EAX nulový.
Není-li počet číslic desetinné části nulový, nastaví se vynuceně příznak požadavku uložení oddělovače desetinných míst. Je-li příznak FORMFLAG_Alt_b nastaven, je požadováno uložení oddělovače desetinných míst, délka textu ve střadači ECX se zvýší o 1. Současně se přičte délka textu znaménka (která může být 0 nebo 1).
|
Délka celočíselné části odpovídá kladné hodnotě exponentu zvýšené o 1. V případě záporného exponentu bude hodnota exponentu omezena na 0. Namísto testu se skokovou instrukcí se použije rychlejší registrová operace. Testem exponentu v registru EBX se zjistí, zda je exponent záporný. Pokud ano, nastavi se obsah registru AL na 1. Pokud ne, bude obsah registru AL nulový.
Dekrementací EAX se připraví do EAX maska, která je nulová v případě záporného exponentu, v případě nezáporného exponentu je 0FFFFFFFFh. Zamaskováním s exponentem v registru EBX se v registru EAX obdrží hodnota exponentu omezená na nulu při záporném exponentu. Po inkrementaci údaje bude registr EAX obsahovat počet číslic celočíselné části.
|
Není-li nastaven příznak FORMFLAG2_Zero, výpočet počtu číslic celočíselné části je hotov a může se přejít k dalšímu vyhodnocování. Jinak se pokračuje zjištením minimálního počtu číslic vyplývajícího z požadované minimální šířky pole s číslem.
Do registru EDX je načtena požadovaná minimální šířka pole s číslem. Po odečtení délky textu desetinné částí se znaménkem v registru ECX se obdrží zbývající šířka pro celočíselnou část. Dál má smysl pokračovat jen je-li zbývající šířka kladná.
Není-li nastaven příznakový bit FORMFLAG2_Thsnd, nepoužijí se oddělovače řádů a registr EDX již přímo obsahuje počet číslic. Pokud se oddělovače řádů mají použít, je nutno odečíst znaky připadající na oddělovače řádů. Inkrementací šířky pole v registru EDX se provede korekce pro započtení první číslice. Vynásobením číslem 3/4 se v registru EDX obdrží počet číslic bez oddělovačů řádů.
Po výpočtu minimálního počtu číslic celočíselné části, vyžadovaného doplněním nul zleva, se minimální počet číslic porovná se skutečně zjištěným počtem číslic v registru EAX a je-li větší, použije se namísto skutečného počtu číslic.
|
Dále je potřeba k délce textu přičíst oddělovače řádů. Nejsou-li oddělovače řádů požadovány (tj. není nastaven příznak FORMFLAG2_Thsnd), bude délka textu odpovídat součtu délky celočíselné části a desetinné části se znaménkem a oddělovačem destinných míst. Jsou-li oddělovače řádů požadovány, je potřeba zjistit jejich počet z počtu číslic celočíselné části.
Do registru EDX se připraví počet číslic celočíselné části snížený o první číslici, která je vždy vyžadována před prvním oddělovačem. Vydělením počtu číslic třemi se obdrží počet celých skupin číslic po 3 znacích, které budou odpovídat počtu oddělovačů řádů. Namísto operace dělení se použije rychlejší operace násobení převrácenou hodnotou. Výsledek se obdrží v registru EDX a přičtením k registru EAX se opraví údaj délky celočíselné části.
|
Na závěr se porovná zjištěná délka textu čísla s požadovanou minimální šířkou pole s textem a je-li menší, navrátí se namísto zjištěné délky textu šířka pole s textem. Po navrácení ukazatele zásobníku se navrátí uschované registry.
Obsah / Utility / TEXTFORM / FltToTextBufN