Obsah / Utility / TEXTFORM / IntToTextBufN
Zdrojový kód: INCLUDE\UTIL\TEXTFORM.INC, UTIL\TEXTFORM.ASM
Související:
IntToTextBuf | Zformátování čísla INT se znaménkem do bufferu | |
FormToTextBufN | Délka formátovaného textu |
IntToTextBufN - Délka textu formátovaného dekadického čísla se znaménkem
Funkce IntToTextBufN zjistí délku formátovaného dekadického čísla se znaménkem v bufferu.
|
Na vstupu funkce obsahuje registrový pár EDX:EAX číslo se znaménkem ke konverzi a registr EBX formátovací parametry FORMPAR (ne ukazatel). Na výstupu je navrácena v registru EAX délka textu.
|
Funkce IntToTextBufN volá interní funkci Int0ToTextBufN, 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 Int0ToTextBufN zjistí délku textu bez uvažování minimální šířky textu. Na vstupu funkce obsahuje registrový pár EDX:EAX číslo se znaménkem 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, EDI a EBP se připraví délka úvodní části před číslem. Obsah registru EBP bude nastaven na 1, pokud má být vždy zobrazeno znaménko nebo má být namísto znaménka zobrazena mezera, v ostatních případech se vynuluje.
Je-li požadované číslo ke konverzi negativní, převede se na absolutní hodnotu a délka úvodní části v registru EBP se nastaví na hodnotu 1 (1 znak pro záporné znaménko).
|
Číslo LOW e uschová do registru EDI a 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 EDI (nižší část čísla) nejvyšší pozice jedničkového bitu. Pokud byl obsah registru EDI 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ů) a odečte se délka úvodní části čísla (znaménko) v registru EBP.
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, přičte se délka úvodní části a střadač je uložen do výstupního registru EAX.
Obsah / Utility / TEXTFORM / IntToTextBufN