Obsah / Utility / TEXTFORM / ExpToTextBufN
Zdrojový kód: INCLUDE\UTIL\TEXTFORM.INC, UTIL\TEXTFORM.ASM
Související:
ExpSToTextBuf | Zformátování čísla s exponentem do bufferu, malé "e" | |
ExpCToTextBuf | Zformátování čísla s exponentem do bufferu, velké "E" | |
MixToTextBufN | Délka textu formátovaného smíšeného desetinného čísla | |
FormToTextBufN | Délka formátovaného textu |
ExpToTextBufN - Délka textu formátovaného čísla s exponentem
Funkce ExpToTextBufN zjistí délku formátovaného čísla s exponentem 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á další 2 registry 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.
Je-li požadována alternativní přesnost, má parametr FORMPAR_Prec formátovacích parametrů význam celkového počtu číslic namísto počtu číslic za desetinnou čárkou. Proto se v tom případě požadovaná přesnost opraví tak, že se sníží o 1. V případě podtečení se omezí na alespoň 1 číslici (není podporována přesnost 0 významných číslic).
|
Čí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 registrového páru EDX:ESI se načte mantisa čísla a do registru EAX exponent. Vynulováním nejvyššího bitu v registru AX se vynuluje znaménkový bit. Je-li exponent v registru AX 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. Exponent se nastaví na normalizovanou hodnotu 3FFFh a zachová se znaménko nuly. Dále se pokračuje obsluhou se zkrácením koncových nul nebo bez zkrácení nul.
|
Má-li exponent v registru AX hodnotu 0FFFFh nebo 7FFFh, jedná se o další zvláštní případ - nekonečno nebo nedefinované číslo. Do registru ECX se připraví délka textu (=7) a funkce může přejít přímo na obsluhu minimální šířky pole s textem.
|
Je-li požadováno ořezání nevýznamných koncových nul (příznak FORMFLAG_Alt2_b), je nutné provést plný rozklad čísla na číslice, aby bylo možné zjistit skutečnou přesnost čísla.
Do registru ECX se připraví ukazatel do bufferu čísla v zásobníku. Po uložení registrů se číslo v registru ST0 zduplikuje a převede na absolutní hodnotu.
|
Vynulováním nejvyššího bitu registru AX se v exponentu vynuluje příznak záporného znaménka čísla a exponent se uloží do registru EDX. 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 je 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, registr ECX obsahuje ukazatel na buffer čísla v zásobníku, registr EBX obsahuje dekadický exponent. Testem příznaku FORMTYPE_Cap_b je funkci předán příznak, zda se má vypnout zaokrouhlování poslední zobrazené číslice.
|
Funkcí FloatTrunc je zjištěna skutečná přesnost čísla (tj. počet platných desetinných míst) a obsahy registrů jsou navrácen. Je-li skutečná přesnost nižší než požadovaná, použije se počet číslic podle skutečné přesnosti.
|
Do registru ECX se připraví požadovaná přesnost, představující počet číslic za oddělovačem desetinných míst. V případě ořezání koncových nul se namísto požadované přesnosti může použít skutečná přesnost čísla.
Požaduje-li se dosazení oddělovače desetinných míst vždy nebo je-li počet číslic za oddělovačem nenulový, zvýší se délka textu v registru ECX o 1.
|
Je-li číslo záporné nebo je-li vynuceně znaménko (nebo náhradní mezera) vyžadováno vždy, je délka textu zvýšena o 1 znak znaménka. Znaménkový bit v registru AX se vynuluje.
|
Ke střadači délky textu v registru ECX se přičte minimální počet znaků na exponent - 1 znak oddělovače exponentu (písmeno "e" nebo "E"), 1 znak pro znaménko exponentu a minimálně 3 číslice exponentu.
Má-li číslo hodnotu 1e+1000 a více nebo 1e-1000 a méně, bude mít exponent 4 číslice a je tedy nutné zvýšit délku textu. Porovnání se pro zrychlení provede testem hodnoty čísla pomocí celočíselných registrů (k rozhodnutí ve většině případů postačí test hodnoty exponentu). Při splnění podmínky se zvýší střadač délky textu ECX o 1.
|
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 / ExpToTextBufN