Obsah / Utility / TEXTFORM / UIntToTextBufN
Zdrojový kód: INCLUDE\UTIL\TEXTFORM.INC, UTIL\TEXTFORM.ASM
Související:
UIntToTextBuf | Zformátování čísla INT bez znaménka do bufferu | |
FormToTextBufN | Délka formátovaného textu |
UIntToTextBufN - Délka textu formátovaného dekadického čísla bez znaménka
Funkce UIntToTextBufN zjistí délku formátovaného dekadického čísla bez znaménka v bufferu.
|
Na vstupu funkce obsahuje registrový pár EDX:EAX číslo bez znaménka ke konverzi a registr EBX formátovací parametry FORMPAR (ne ukazatel). Na výstupu je navrácena v registru EAX délka textu.
|
Funkce UIntToTextBufN volá interní funkci UInt0ToTextBufN, která nezapočítává požadovanou šířku pole. Porovnáním s požadovanou minimální šířkou se ověří, zda je délka textu čísla větší než požadovaná minimální šířka. Pokud je menší, navrátí funkce požadovanou minimální šířku namísto délky textu bez mezer.
|
Funkce UInt0ToTextBufN zjistí délku textu bez uvažování minimální šířky textu. Na vstupu funkce obsahuje registrový pár EDX:EAX číslo bez znaménka ke konverzi a registr EBX formátovací parametry FORMPAR (ne ukazatel). Na výstupu je navrácena v registru EAX délka textu.
|
Po úschově obsahu registrů EDX a EDI se uschová nižší část dekódovaného čísla do registru EDI.
|
Testem registru EDX se rozliší, zda má číslo velikost DWORD (1 dvojslovo) nebo QWORD (2 dvojslova).
Má-li číslo rozměr DWORD, vyhledá se v registru EAX (nižší část čísla) nejvyšší pozice jedničkového bitu. Pokud byl obsah registru EAX nulový, nastaví se příznak ZF. To využije následující instrukce SETZ, která uloží do registru AH hodnotu 1 v případě nulového obsahu čísla, jinak do AH uloží 0. Přičtením 1 k AL se obdrží v registru AL počet bitů původního čísla LOW. Avšak pokud byl obsah čísla LOW nulový, je obsah registru AL nedefinovaný. Proto je AL zamaskován maskou vygenerovanou z příznaku ZF v registru AH. Výsledkem je, že registr AL obsahuje buď počet bitů v původní nižší části čísla nebo nulu pokud byla nižší část čísla nulová.
Počet bitů se přepočte na počet číslic a to tak, že se počet bitů nejdříve vynásobí poměrem dvojkového a dekadického logaritmu. Vznikne přibližný počet dekadických číslic, zaokrouhleno dolů, který se uloží do registru EDX. Stejně jako u funkce UDWToTextBufN se počet číslic upřesní pomocí tabulky IntMul10.
|
Má-li číslo rozměr QWORD (2 dvojslova), vyhledá se v registru EDX (vyšší část čísla) nejvyšší pozice jedničkového bitu. Obsah registru EDX nebyl nulový, proto není třeba obsluhovat případ nuly. Zvýšením pozice bitu o 32+1 bude registr AL obsahovat počet bitů čísla.
Zjištěný binární logaritmus bude převeden na dekadický logaritmus vydělením číslem ln 10 / ln 2 = 3,3219 (přibližně). Namísto dělení se použije rychlejší operace násobení převrácenou hodnotou, tj. číslem 100h / 3.3219 (zaokrouhleno nahoru). Po převzetí výsledku z registru AH se v registru EAX obdrží výsledný dekadický logaritmus (přesněji jeho celočíselná část).
|
Přibližný počet číslic je již známý, ale údaj je potřeba ještě upřesnit, protože binární logaritmy mohou ležet přes hranici dekadických logaritmů. K tomu slouží tabulka Int2Mul10, která obsahuje dekadické mocniny, tedy čísla 1e10, 1e11 atd. Porovnáním původního čísla s hranicí podle vypočteného dekadického logaritmu čísla se upřesní, zda číslo leží nad hranicí nebo pod hranicí a pokud leží nad hranicí, počet číslic se zvýší o 1.
|
Vypočtená délka čísla se zvýší podle požadovaného minimálního počtu číslic (zadaného položkou FORMPAR_Prec formátovacích parametrů).
|
Další výpočet musí zajistit doplnění nul k číslu, je-li aktivní příznakový bit FORMFLAG_Zero_b.
Do registru EAX se připraví požadovaná minimální šířka pole (z registru BH, tj. parametr FORMPAR_Width formátovacích parametrů).
Je-li požadován oddělovač řádů (přepínač FORMFLAG_Thsn_b), musí se od počtu znaků odečíst počet oddělovačů. Na 3 číslice připadá 1 znak oddělovače, přičemž před oddělovačem musí být vždy minimálně 1 číslice, proto počet číslic pro danou šířku pole EAX se vypočte inkrementací šířky pole o 1 a vynásobením číslem 3/4.
Po výpočtu počtu číslic potřebných k doplnění čísla nulami se výsledek porovná se skutečnou šířkou čísla a případně se počet číslic zvýší.
|
Je-li požadován oddělovač řádů (je nastaven přepínač FORMFLAG_Thsn_b), je potřeba k délce čísla přičíst oddělovače řádů. Na 3 číslice čísla připadá 1 oddělovač řádů, přičemž před oddělovačem musí být minimálně jedna číslice. Proto se počet oddělovačů získá snížením počtu číslic o 1 a vydělením údaje třemi. Vypočtený počet oddělovačů se přičte ke střadači délky textu v registru EDX, který je nakonec uložen do výstupního registru EAX.
Obsah / Utility / TEXTFORM / UIntToTextBufN