; Vaším úkolem je napsat program, který sečte dvě 16bitová čísla ; s plovoucí desetinnou čárkou ve formátu podobnému IEEE 754 ; ‹binary16›. Oproti skutečnému IEEE si práci v několika ohledech ; zjednodušíme: ; ; • mantisa nebude používat implicitní bit, tzn. v nenulovém ; normalizovaném čísle bude mít vždy na nejvyšší pozici jedničku, ; • nebudeme uvažovat subnormální čísla, nekonečna ani hodnoty NaN ; (vstupem jsou tedy vždy normalizovaná konečná čísla), ; • budeme předpokládat, že nedojde k přetečení (tzn. výsledek je ; vždy možné reprezentovat), ; • zaokrouhlovat budeme vždy pouze ořezáním, tzn. směrem k nule, ; • prohodíme mantisu a exponent,¹ tzn. od nejvyššího bitu je ; nejprve znaménkový bit (1 = záporné, 0 = kladné), následuje 10 ; bitů mantisy a 5 bitů exponentu. ; ; Výsledek sčítání nechť je také normalizovaný a je-li nulový, ; exponent i znaménkový bit budou také nulové. ; ; Exponent je v aditivním kódování, ale protože jeho absolutní ; hodnota pro sčítání nehraje roli (důležitý je pouze rozdíl dvou ; exponentů), můžeme jej interpretovat jako pětibitové celé číslo ; bez znaménka. ; ; Vstupní hodnoty jsou uloženy v registrech ‹l1› a ‹l2›. Výsledek ; zapište do registru ‹rv› a skočte na návěstí ‹check›. Hodnotu ; v registru ‹l7› neměňte. ; V implementaci můžete použít následovný algoritmus: ; ; 1. vstupní hodnoty rozeberte na znaménkový bit, mantisu a ; exponent, ; 2. podle rozdílu exponentů zarovnejte mantisy „pod sebe“, tzn. ; tak, aby ⟦k⟧-tý bit jedné i druhé mantisy odpovídal ⟦n⟧-tému ; řádu; posuvy mantis provádějte tak, abyste zachovali 15 ; bitů přesnosti (přesto se v tomto kroku může stát, že některé ; bity vstupu ztratíme, např. při výpočtu 2¹⁰ + 2⁻⁸), ; 3. srovnejte znaménkové bity a zarovnané mantisy a podle potřeby ; proveďte součet nebo rozdíl a nastavte výsledný znaménkový ; bit (při sčítání nezapomeňte na případný přenos), ; 4. výsledek normalizujte (nejvyšší bit výsledné mantisy musí být ; jedna) – v tomto kroku dostanete výsledný exponent, ; 5. složte výsledek z vypočtené mantisy, exponentu a znaménkového ; bitu. ; ; Příklad: uvažme vstupy ‹x₁ = 0xc010›, ‹x₂ = 0x4011›, hledáme ‹x₀ = ; x₁ + x₂›: ; ; 1. získáme znaménkové bity ‹s₁› = 1, ‹s₂› = 0, ; 2. mantisa ‹m₁ = 0x200›, ‹m₂› stejně tak, ; 3. abychom dosáhli potřebné přesnosti, mantisy posuneme o 5 bitů ; doleva, tzn. dostaneme v obou případech ‹0x4000›, ; 4. exponenty jsou kódovány jako ‹e₁ = 0x10› a ‹e₂ = 0x11› (tyto ; hodnoty značí „absolutní“ exponenty 1 a 2), jejich rozdíl je ; tedy 1 ve prospěch ‹e₂› a jako prozatímní exponent výsledku si ; proto poznačíme ‹e₀ = e₂›, ; 5. mantisu ‹m₁› posuneme o jeden bit doprava: ‹m₁' = 0x2000›, ; 6. protože znaménkové bity jsou různé, budeme odečítat – abychom ; předešli přetečení, odečítáme vždy menší číslo od většího, ; tzn. ‹m₀ = m₂ - m₁' = 0x4000 - 0x2000 = 0x2000›, ; 7. znaménkový bit výsledku bude jistě ‹s₀ = 0›, ; 8. první nenulový bit výsledné mantisy ‹m₀› je na druhé ; nejvýznamnější pozici, ale normalizace vyžaduje, aby byl ; nenulový nejvyšší bit – proto ‹m₀› posuneme o jednu pozici ; doleva a ‹e₀› o jedničku snížíme, ; 9. mantisu ořízneme na výsledných 11 bitů přesnosti a z takto ; získaných ‹s₀›, ‹m₀› a ‹e₀› složíme hledané ‹x₀›. ; ; Dobře si rozmyslete vnitřní reprezentaci jednotlivých částí ; (zejména mantisy). Formát čísel je navržen tak, aby se ; minimalizoval potřebný počet bitových posuvů. ; ¹ Ve formátu IEEE je exponent ve vyšších bitech zejména kvůli ; jednoduchosti srovnání, to ale v tomto příkladu implementovat ; nebudeme. test: ld l7, data → l1 add l7, 2 → l7 ld l7, data → l2 add l7, 2 → l7 eq l1, 0xffff → t1 ; test-end marker jz t1, solution halt data: ; l1 + l2 → rv .word 0x0000, 0x4010, 0x4010 ; 0 + 1 = 1 .word 0x4000, 0x4010, 0x4010 ; 1 + 1 = 2 .word 0xc010, 0x4010, 0x0000 ; 1 - 1 = 0 .word 0xc010, 0x4011, 0x4010 ; 2 - 1 = 1 .word 0x4000, 0x4001, 0x6001 ; 1 + 2 = 3 .word -1 check: ld l7, data → t1 eq rv, t1 → t1 asrt t1 add l7, 2 → l7 jmp test .trigger set _tc_expect_ 5 .trigger inc _tc_ solution: ; zde začíná řešení