Gonda János
SZÁMÍTÓGÉPI MATEMATIKA
Budapest, 2007
Lektorálta:
3
TARTALOMJEGYZÉK
ELİSZÓ
5
ANALÓG ÉS DIGITÁLIS SZÁMÍTÓGÉP, ALGORITMUS, NEUMANN-ELV
7
JELÁTALAKÍTÁS
9
SZÁMÁBRÁZOLÁS
19
DIGITÁLIS ARITMETIKA
49
LOGIKAI ALGEBRA
77
A HIBAKORLÁTOZÁSRÓL
87
PÉLDÁK
93
FELADATOK
101
A tárgyalt anyaghoz kapcsolódó feladatok
104
Egyéb, a számítógépek felépítéséhez tartozó feladatok
107
Megoldások
112
TÁRGYMUTATÓ
127
IRODALOMJEGYZÉK
131
5
ELİSZÓ A következı oldalakon található anyag a számítógépek mőködésének a leginkább a matematikához kapcsolódó részével, az aritmetikai és logikai mőveletek végrehajtásának elveivel, valamint a végrehajtáshoz szükséges adatok megadásának módjaival, az egyes megadási módok tulajdonságaival, elınyeivel, hátrányaival, leggyakoribb felhasználási területeivel, továbbá a számítógépben vagy adatátvitelnél történı hibák korlátozásának alapjaival foglalkozik. Az elsı részben tisztázzuk, hogy milyen elven mőködtek és mőködnek a számítógépek, és bemutatjuk a számítógépek felépítése szempontjából alapvetı fontosságú Neumann-elvet. A Neumann-elvbıl következik, hogy a számítógéppel feldolgozandó adatok egy jelentıs részét a feldolgozás elıtt megfelelı módon át kell alakítani, mivel ezek a gépek csak „számjegyes” formában, azaz valamilyen ábécével felírt formában rendelkezésre álló adatokat képesek manipulálni. Jóllehet a mai számítógépek minden adatot bináris alakban tárolnak, és legalsó szinten minden mőveletet bináris adatokon végeznek, szükséges egyéb ábrázolási formákat is megismerni. Ennek két oka is van: egyrészt magasabb, de még mindig gépi szinten maradva, más számrendszerekben megadott számokkal is dolgozik a számítógép, másrészt a fogalmi tisztánlátáshoz mindenképpen az általános elvek ismeretére van szükség. Tanárok esetében ez utóbbi indok különösen nagy súllyal esik latba, ugyanis míg egy általános vagy középiskolás diáknak elsısorban azt kell tudnia, hogy hogyan kell valamit csinálni, a tanárnak mindenképpen tisztában kell lennie azzal is, hogy miért úgy kell csinálni. Ehhez viszont szilárd elvi alapokra van szükség. Foglalkozunk a logikai algebrával. Ennek szintén igen nagy jelentısége van a számítógépekkel kapcsolatban. A számítógépek alapvetıen aritmetikai és logikai mőveleteket végeznek, így eleve szükséges a logika mőveleteinek ismerete. Egy másik, legalább ennyire fontos ok, hogy, mint majd látjuk, a valóságos számítógépek szinte teljes egészükben olyan részegységekbıl épülnek fel, amelyek lényegében véve a logika alapmőveleteit, az ÉS, a VAGY és a NEM mőveleteket, illetve ezek egyszerő kombinációit hajtják végre. Ha tehát valaki tisztában van ezen mőveletek tulajdonságaival, akkor elvben már saját maga is képes lehet szinte teljes számítógép megalkotására. Igen röviden és nagyon bevezetı szinten bemutatjuk, hogy hogyan lehet a tárolás illetve átvitel során keletkezı hibák egy részét detektálni, sıt, esetleg javítani. Végül néhány példát mutatunk, megoldással együtt, az adatábrázolás témakörébıl. A tanulás megkönnyítése, a könnyebb keresés és tájékozódás kedvéért a jegyzet végén egy tárgymutató található.
7
ANALÓG ÉS DIGITÁLIS SZÁMÍTÓGÉP, ALGORITMUS, NEUMANN-ELV A mai számítógépek pontosabb megnevezése elektronikus digitális számítógép. Az elektronikus jelzı értelme egyszerő, azt fejezi ki, hogy a gép elektronikus alkatrészekbıl épül fel (mindazt, amit elektronikusan meg lehet oldani, fel lehet építeni mechanikus, hidraulikus, tehát folyadékkal mőködı, és pneumatikus, azaz levegıvel mőködtetett alkatrészekbıl is, csak lényegesen nagyobb méretben és alacsonyabb mőködési sebességgel). Nézzük a másik jelzıt. Ennek is csak akkor van értelme, ha létezik másfajta számítógép is. A számítógépek másik típusa az analóg számítógép. Ezek a gépek egy matematikai kifejezés megoldását adják. Különbözı speciális feladat kiszámítására alkalmas részegységet tartalmaznak: összeadó, kivonó, szorzó, osztó, differenciáló, integráló áramköröket, valamint matematikai függvényeket – többek között szögfüggvényt, logaritmus- és exponenciális függvényt – generáló áramköröket stb., vagyis ha például egy integráló áramkör bemenetére egy idıben lineárisan váltózó nagyságú feszültséget adunk, akkor a kimenetén az idıben négyzetesen változó feszültség jelenik meg. Minden ilyen alapáramkörbıl több van a gépbe beépítve, és ha egy matematikai kifejezést kell kiszámítani, akkor az abban szereplı minden egyes mőveletet egy-egy megfelelı áramkör végez, amelyeket a képletnek megfelelıen egy dugaszolható táblán kötnek össze. Egy ilyen berendezés attól analóg, hogy az információt képviselı érték egy vele egyértelmő matematikai kapcsolatban álló feszültség, vagyis egy mérhetı fizikai mennyiség nagysága, egy analóg jel. A digitus latin szó, jelentése (hüvelyk)ujj. Mivel az ember kezét-lábát is felhasználja a számoláshoz, ezért ez a szó késıbb a számjegyet is jelentette, és az angolban ennek megfelelıen a digit jelentése számjegy. Ez máris mutatja, hogy a digitális számítógép számjegyekkel megadott adatokkal, digitális jelekkel dolgozik. Természetesen ezekben a gépekben is valamilyen fizikai mennyiség reprezentálja az adatot, ám közvetetten: ha egy megadott ponton mért feszültség kisebb mondjuk 1 Voltnál, akkor az a 0-s számjegyet, míg ha ez az érték például 3 Voltnál nagyobb, akkor az 1-es számjegyet jelenti. A két megadott érték közötti feszültség hibát jelent. Míg egy analóg gépben minden részegység valamekkora hibával állítja elı a számítás eredményét, és ezek a hibák halmozódnak, addig a digitális gép – bizonyos feltételek betartásával – pontosan azt az eredményt adja, amelyet ugyanolyan számítással papíron és ceruzával számolva mi is kapnánk (de hangsúlyozzuk, hogy ugyanazzal a számítással, tehát például az integrálást ugyanúgy numerikusan végezve). A továbbiakban csak a digitális számítógéppel foglalkozunk. A digitális számítógép algoritmust hajt végre. Az algoritmus egy adott feladat megoldásának leírása: vannak olyan alapmőveletek, amelyeket gondolkodás nélkül végre tudunk hajtani, és az algoritmus azt adja meg, hogy egy alapmővelet végrehajtása után mi a soron következı lépés. Az algoritmus egy véges ábécével felírt véges hosszúságú szöveg, amelyhez hozzátartozik az is, hogy mely adatokon operál. Magát az adatot is egy véges ábécével felírt véges hosszúságú sorozat reprezentálja. A megengedett adatok száma akár végtelen is lehet, hiszen az adat hosszúságára nincs megkötés. A végtelen sok különbözı adaton végrehajtva ugyanazt az algoritmust, az algoritmus lefutása akár végtelen sok különbözı módon történhet, ugyanakkor az algoritmus leírása véges. Ez a leírás pontosan rögzíti, hogy ha egy adott adaton végrehajtottunk egy lépést, és létrejött ennek a lépésnek az eredménye, akkor mi lesz a soron következı lépés. Ez nyilván függhet a konkrét bemeneti adattól is. Egy tipikus példa az egész számok legnagyobb közös osztóját kiszámító euklideszi algoritmus. Emeljük ki az algoritmus elıbb megadott lényeges tulajdonságait: • véges sok alapmővelet; • véges ábécével reprezentált véges hosszúságú adatok; • a részeredményektıl függı, pontosan meghatározott végrehajtási sorrend, amelyet egy véges ábécével felírt véges szöveggel adunk meg; • szekvenciális, vagyis lépésenként egymás utáni végrehajtás.
8
ANALÓG ÉS DIGITÁLIS SZÁMÍTÓGÉP, ALGORITMUS, NEUMANN-ELV
Többé-kevésbé a fent megadott elvek alapján épülnek fel a digitális számítógépek, és szinte teljesen megfelelnek a fentieknek a ma túlnyomó többséget adó Neumann-elvő számítógépek. A digitális számítógépben az alapmővelet a gép által egy lépésben végrehajtott utasítás, és az algoritmus a program. Ha a gép egyetlen algoritmus végrehajtására képes, akkor célszámítógép, ellenkezı esetben univerzális számítógép. A Neumann-elvet az alábbiakban foglalhatjuk röviden össze: • a kettes számrendszer mint véges ábécé használata; • egy utasítás-végrehajtó egység, ennek következtében szekvenciális végrehajtás; • a szekvenciális végrehajtás következtében a részeredmények tárolása szükségessé teszi memória alkalmazását; • az univerzális mőködést a feladat megoldását szolgáló program adja, vagyis a gépnek különbözı programokkal kell mőködnie. A programot, tehát az algoritmust, véges ábécével adhatjuk meg. Ez a véges ábécé kételemő, azaz az adatok megadásához hasonlóan a kettes számrendszer, vagyis a programot is kettes számrendszerben írjuk fel. Mivel így formailag az adatok és az utasítások teljesen egyformák, ezért a programot az adatokhoz hasonlóan a memóriában tárolhatjuk, így ezek a gépek tárolt programú számítógépek. Mint mondtuk, vannak ettıl bizonyos pontokon eltérı mőködéső digitális számítógépek is, ám jelenleg a hétköznapokban használt számítógépek szinte kizárólag Neumann-elvőek, vagy legalábbis majdnem teljesen ilyen elven mőködnek, ezért mostantól kezdve a számítógép a Neumann-elvő elektronikus digitális számítógépet jelenti. Foglalkozzunk röviden a kettes számrendszer használatával. Ennek részben mőszaki, részben matematikai háttere van. A mőszaki megfontolás könnyen érthetı: ebben az esetben csak két különbözı állapotot kell megkülönböztetni, például hogy egy adott vezetéken folyik-e áram vagy nem, sıt, ezt sem abszolút pontossággal, hiszen a korábbi példában már láttuk, hogy csupán azt kell tudni eldönteni, vajon a feszültség kisebb-e 1 Voltnál, vagy nagyobb, mint 3 Volt. Ha a szokásos tízes számrendszert használnánk, akkor tíz különbözı szimbólumot kellene mőszakilag reprezentálni, mondjuk tíz különbözı feszültséget kellene egymástól megkülönböztetni, amely lényegesen nagyobb arányban eredményezne tévedést, tehát hibát. Tekintettel arra, hogy a számítógéppel feldolgozandó adatok gyakran nem digitális alakban állnak rendelkezésre, foglalkoznunk kell azzal a kérdéssel, hogy az ilyen adatokat hogyan tudjuk átalakítani a digitális számítógép által elfogadott jelekké.
Számítógépi matematika
9
JELÁTALAKÍTÁS A digitális számítógép véges hosszúságú számok formájában megadott adatokkal végzi a mőveleteket, tehát a bemenetén is ilyen adatokat vár, és a kimenetén hasonló formában jelentkezik az eredmény. Az esetek egy jelentıs részében (fıleg mőszaki-tudományos problémáknál) azonban a megoldandó feladat kiinduló adatai nem ilyen formájúak. Nézzük például azt az esetet, amikor egy árvíz-felügyeleti rendszert akarunk számítógéppel kiépíteni. Egy bemeneti adat esetünkben a folyó vízszintje, amelyet egy adott idıszakban példaként az alábbi 1. ábra mutat. h(t)
0
t 1. ábra
Ennek a függvénynek számunkra két fontos tulajdonsága van: 1. tetszıleges idıpillanatban értelmezett, hiszen a folyónak mindig van valamilyen vízszintje; 2. a vízszint nem állandó, így a függvény nem konstans, és a vízszint változása folytonos, ezért a függvény egy adott véges, nem nulla hosszúságú tartományban bármilyen értéket felvesz. Mindkét fenti tulajdonság kellemetlen (mármint a digitális technika szempontjából). Tetszıleges véges, nullánál hosszabb idıintervallum végtelen sok idıpontot tartalmaz, vagyis a bemeneti információhalmaz bármely véges, egynél több idıpontot tartalmazó idıintervallum esetén végtelen sok elemő, azaz végtelen sok szám (bármely két valós szám között van mindkét elıbbitıl különbözı valós szám, innen adódik, hogy ha az intervallum tartalmaz két pontot, akkor végtelen sokat tartalmaz). A Neumann-elven mőködı gép a feldolgozást egyetlen feldolgozóegységgel, szekvenciálisan végzi, és mindenegyes lépéshez nullánál hosszabb idıre van szükség, ebbıl következıen véges idı alatt csupán véges számú lépés elvégzésére alkalmas, a gép véges idı alatt nem képes a végtelen sok adat feldolgozására. A 2. tulajdonság nem ugyanezt, de hasonló problémát vet fel. A gép egy véges szimbólumhalmaz elemeibıl összerakott véges, rögzített hosszúságú – vagy legalábbis egy rögzített hosszúság néhány kis egész számú többszörösének megfelelı hosszúságú – sorozatok feldolgozására alkalmas, és az ilyen sorozatok száma véges. Ugyanakkor a bemeneti információk számához hasonlóan a lehetséges értékek halmaza is végtelen, ami a konkrét esetben azt jelenti, hogy az összes lehetséges folyószintet nem tudjuk a gép nyelvén megadni, nem tudjuk pontosan leírni. Valamilyen technikát kell keresni, hogy a számítógép az ilyen jeleket is kezelni tudja. A két probléma megoldását külön vizsgáljuk. Mintavételezés, A folyamatosan változó, tehát bármely idıpillanatban értelmezett függvényhez egy új függvényt rendelünk úgy, hogy a függvényt csupán diszkrét idıpillanatokban tekintjük. A vízszintfügg-
JELÁTALAKÍTÁS
10
vény valamely véges szakasza esetén a 2. ábra függvényére jutunk, és az eredeti függvény görbéjének elhagyásával a 3. ábra görbéjét kapjuk.
h(t)
0
t1 t2
t3
t 4 t5
t6 t7
t8 t9 t10 t11 t12
t13
t
t8 t9 t10 t11 t12
t13 t
2. ábra
hmv (t)
0
t1 t2
t3
t4 t5
t6 t7
3. ábra
Természetesen a minták az idıben a mínusz végtelenben kezdıdnek és a plusz végtelenig tartanak, a bemutatott ábrák ennek csupán egy véges szakaszát jelképezik. Ha most hmv -nek egy véges szakaszát nézzük, akkor ebben már csak véges sok minta, azaz véges sok adat van, amit a gép képes kezelni (feltéve, hogy az egyes adatok kezelhetıek a gép által). A fenti eljárást mintavételezésnek nevezzük, a t i -k a mintavételi idıpontok, hmv a mintavételezett függvény. A bemutatott függvénynél a mintavétel idızítésében semmi szabályszerőség nincs. Célszerőbb, ha az egyes mintavételi idıpontok azonos távolságban követik egymást, ekkor a mintavételezést egyenletesnek mondjuk. Egyenletes mintavételezésnél a mintavételi idıpontok a t k = k ⋅ ∆t kifejezéssel adhatóak meg, ahol ∆t > 0 a két egymást közvetlenül követı mintavétel közötti idı. Az eredeti függvényünket az egyenletes mintavételezéssel mutatja a 4. ábra, és ismét csak a lényeges rész megtartásával a 5. ábra. Felmerül a kérdés, hogy csupán a minták ismeretében meg tudjuk-e adni a teljes eredeti görbét. Ránézve a mintavételezett függvény ábrájára azonnal szembeötlik, hogy ez szegényebb, ami az információtartalmat illeti, mint az eredeti függvény, hiszen két mintavétel közötti idıben semmit nem mond az eredeti függvényrıl. Ez egy elég természetes elképzelés, és az ember hajlamos a „természetes” dolgokat eleve igaznak tekinteni. Szerencsére mindig vannak kételkedı elmék, akik már sok
Számítógépi matematika
11
„szemléletes igazság”-ról kimutatták, hogy esetleg szemléletesek, de nem igazak. A mi esetünkben egy Claude Shannon nevő matematikus volt az, aki nem hitt a szemének, és egy kicsit mélyebben utánanézett a dolognak.
h(t)
∆t
0
t1
t2
t3
t4
t5
t6
t7
t8
t9
t10
t11
t12 t
t7
t8
t9
t10
t11
t12
4. ábra
hemv (t)
0
t1
t2
t3
t4
t5
t6
t
5. ábra
Ha a függvény eleget tesz bizonyos feltételeknek, akkor elıállítható végtelen sok, különbözı periódusidejő, amplitúdójú és fázisú szinusz-függvény összegeként (vagy integráljaként). Amennyiben egy ilyen függvény sávhatárolt, vagyis egy bizonyos, a függvénytıl függı maximális frekvenciánál nagyobb frekvenciájú komponens nem szerepel a függvény felbontásában, akkor ezen maximális frekvencia kétszeresénél sőrőbb mintavétel esetén a mintákból egyértelmően visszaállítható a teljes eredeti függvény. Nagyon durván szólva a függvény akkor sávhatárolt, ha nincsenek benne hirtelen változások, és a maximális frekvencia a függvény változási sebességétıl függ, nevezetesen, minél gyorsabb változások lépnek fel egy függvényben, annál nagyobb a sávhatár (ha egyáltalán sávhatárolt a függvény). Még egy lényeges megjegyzés. Természetesen a függvények elenyészı töredéke sávhatárolt, hiszen általában egy függvény idıhatárolt, így a mintavett jel nem hordoz minden információt az eredeti függvényrıl, következésképpen ez nem is állítható vissza teljes egészében a mintákból. Azt viszont így is látjuk, hogy ha olyan frekvenciával vesszük a mintákat, amely frekvenciánál szaporábban változó összetevık már csak igen kis amplitúdóval vesznek részt a függvényben, akkor a visszaállítás viszonylag kis hibával elvégezhetı. A most elmondottak persze nem precíz matematikai kijelentések, de alaposabb elemzéssel azzá tehetıek.
12
JELÁTALAKÍTÁS
Szemlélet alapján az elmondottak azt fejezik ki, hogy ha egy jel sávhatárolt, akkor nem tartalmaz egy bizonyos frekvenciánál nagyobb frekvenciájú összetevıket, azaz nem változik túlságosan gyorsan, ezért, ha elég gyakran vesszük a mintákat, akkor két mintavétel között viszonylag keveset változik a függvény, így a minták összessége alapján (vagyis az adott idıponthoz képest jövıbeni minták is lényegesek) meghatározható egy közbülsı pontban is a függvény értéke. Példaként nézzük a 6. ábra görbéjét. Itt 26 szinusz-függvény összege látható, és könnyen észrevehetı, hogy ez az összeg egy igen jó közelítését adja egy úgynevezett négyszög-függvénynek. További megfelelıen választott szinusz-függvény hozzávételével az eredı függvény egyre jobban kisimul, és egyre jobban megközelíti a négyszögfüggvényt, természetesen úgy, hogy a szakadási pontokban a jobb- és bal oldali határérték közepéhez konvergál a sorozat.
6. ábra
Számítógépi matematika
13
f(t)
1
-3T/4
T/4
-T/4
3T/4
t
7. ábra
Most áttérünk a másik probléma feloldására. Kvantálás Visszaemlékszünk, hogy a második nehézséget az okozza, hogy a függvényértékek halmaza végtelen, leszámítva a konstans függvény esetét, amely jelen tárgyalásunk szempontjából teljességgel érdektelen, és ezt a végtelen sok adatot nem tudjuk véges sok jel véges hosszúságú sorozatával leírni. Most a következıképpen járhatunk el. Legyen C véges sok, páronként diszjunkt, nullánál hosszabb I k intervallum halmaza, amelyek együtt kiadják az I értékkészletet. I k -hoz injektíven hozzárendelünk egy rk egész számot, és definiáljuk a hkv (t ) = rk függvényt, ahol h (t ) ∈ I k . Az elıbb említett rk -t például a következı módon határozhatjuk meg. Ha I-t csak végtelen intervallumokkal fedtük le, akkor vagy egyetlen, vagy két részintervallumunk van, és ez(ek) tartalmaz(nak) egész számot. Ellenkezı esetben, vagyis amikor a fedı intervallumok között van véges, legyen s az I k intervallumok hosszának minimuma. Ez létezik, hiszen véges sok intervallumról van szó, és s > 0 , mert kikötöttük, hogy az I k -k mindegyike nullánál nagyobb hosszúságú. Ha 0 < δ < s , akkor valamennyi I k -hoz van olyan rk egész, hogy c k = rk δ eleme I k -nak, és ha δ-t választjuk mértékegységnek, akkor c k mérıszáma rk (ismét megjegyezzük, hogy az intervallumhoz rendelt egész bármilyen lehet az injektivitás megtartása mellett, nem szükségszerő, hogy valamilyen egységgel a megfelelı pontok hozzátartozzanak a intervallumukhoz, de azért mégis azt tartjuk természetesnek, ha az intervallum és a neki megfeleltetett egész nem teljesen idegenek). A leírt eljárás a kvantálás, az I k intervallumok a kvantumok, és hkv (t ) a kvantált függvény, amely a vízszint esetén az alábbi 8. ábra, illetve a csupán a jobb megértés kedvéért berajzolt vonalak elhagyása után a 9. ábra (persze két szomszédos intervallum esetén az elválasztó pont csak az egyikhez tartozik hozzá, és ettıl függıen a 9. ábra lépcsıs függvényén is egyértelmő, hogy a szakadási pontokban mi a függvény értéke). A mintavételezéshez hasonlóan itt sem célszerő a teljesen tetszıleges felosztás és reprezentánsválasztás. Az egyik, és leggyakrabban célszerő választás, ha a részintervallumok – leszámítva az esetleg végtelen alsó illetve felsı intervallumot – azonos hoszszúságúak, és a reprezentáns az adott intervallum alsó, felsı vagy felezı pontja – ismét eltekintve esetleg a szélsı intervallumok egyikétıl vagy mindkettıjüktıl. Ezt egyenletes kvantálásnak mondjuk. Esetenként célszerő lehet más szabályossággal felosztani az értékkészletet. Ha például a kvantálandó függvény a hang intenzitása, akkor a nagyobb intenzitások felé exponenciálisan nıhet az intervallu-
JELÁTALAKÍTÁS
14
mok hossza, ami azért lehet célszerő, mert az emberi fül logaritmikusan érzékeny a hang erısségére, vagyis a százszoros intenzitásváltozást csupán kétszer akkora hangerısség-változásnak találja, mint amikor az intenzitás eredeti értékének tízszeresére nı. Az egyenletes kvantálást mutatja a példánkra a 10. ábra, és a fölösleges vonalak nélkül a 11. ábra.
I4
h(t) c4 c3
I3 I2
c2 c1
I1
δ 0
t 8. ábra
hkv (t) c4 c3 c2 c1
0
t 9. ábra
Számítógépi matematika
15
h(t) I5 I4 I3 I2 I1
c5 c4 c3 c2 c1
δ
0
t 10. ábra
hekv (t) c5 c4 c3 c2 c1
0
t 11. ábra
Mivel az új függvényértékek egész számok, ezek megadhatóak a kívánt módon, azaz véges ábécé elemeivel felírt véges hosszúságú szóként. Egyenletes kvantálás esetén ezt könnyő formulával megadni: ha az önkényesen kijelölt r-edik intervallum alsó pontja m r , az egyes intervallumok (azonos) hossza d, és ∆ = c 2 − c1 , vagyis ∆ a két szomszédos intervallumhoz rendelt érték különbsége, továbbá h(t )∈ I r akkor f (t ) − m r hekv (t ) = c r + ∆ . d
Ismét felmerül a kérdés, hogy a kvantált jelbıl elıállítható-e az eredeti. Az biztosan nem várható, hogy ez minden korlátozás nélkül tetszıleges függvényre igaz legyen, ezért legyünk szerényebbek: legalábbis valamely jól körülírható, meghatározott függvényosztály esetén lehetséges-e a rekonstrukció. A válasz most nemleges, amint a következı két függvény alapján ez eléggé nyilvánvaló és szemléletes (12. ábra).
JELÁTALAKÍTÁS
16
f2(t)
f 1(t)
0
0
t
t
12. ábra
Ha a teljes értékhalmaz egyetlen kvantumba esik, akkor a két függvény kvantálás után azonos, és mivel bármilyen kicsi kvantum esetén lehet két függvény a fentihez hasonló, ezért látjuk, hogy most kivihetetlen a teljes visszanyerés. Mindazonáltal gondoljuk meg, hogy minden mérés illetve átalakítás valamilyen hibával terhelt, aminek egyrészt mőszaki, de másrészt megkerülhetetlen és ezért elháríthatatlan fizikai okai vannak. Ha tehát az egyes kvantumok értéke nagyságrendileg megegyezik a hiba mértékével, akkor a valóságos helyzethez képest nem veszítünk információt. Nyilvánvaló, hogy az eredeti problémát önmagában sem a mintavételezés, sem a kvantálás nem oldja meg, csak a kettı együtt, így jutunk a 13. ábra, és a lényegtelen információk elhagyása után a 14. ábra mintavett kvantált jeléhez. Egyenletes mintavételezéssel és egyenletes kvantálással a megfelelı két függvényt a 15. ábra és a 16. ábra mutatja.
h(t) I4 I3 I2 I1
c4 c3 c2 c1
δ 0
t1 t 2
t3
t4 t5
t 6 t7
t8 t9 t10 t11 t12
t13 t
t8 t9 t10 t11 t12
t13 t
13. ábra
hmvk (t) c4 c3 c2 c1
0
t1 t 2
t3
t4 t5
t 6 t7
14. ábra
Számítógépi matematika
17
h(t) ∆t I5
c5
I4
c4
I3
c3
I2
c2 c1
I1
δ
0
t1
t2
t3
t4
t5
t6
t7
t8
t9
t10
t11
t12
t
t7
t8
t9
t10
t11
t12
t
15. ábra
hemvk (t) c5 c4 c3 c2 c1
0
t1
t2
t3
t4
t5
t6
16. ábra
A mintavett kvantált jellel elértük célunkat: a minták száma véges idıintervallumon véges, és a minták egy közös egység egész számú többszörösei, így a megfelelı egészek a számítógép által elfogadott formában adhatóak meg. Ha a mintavett kvantált jelet számjegyes formában adjuk meg (természetesen a gép számára az általa értelmezhetı formában), akkor az eredeti analóg jelet digitális jellé alakítottuk, vagyis az analóg-digitál átalakítás (A/D konverzió) mintavételezésbıl, kvantálásból, és a mintavett kvantált jel számjegyes megadásából áll. Amennyiben a számítás eredménye is függvény, akkor persze ez is a valóságos eredmény mintavett és kvantált megfelelıje. Ha az igazi függvény minden idıpontban értelmezett, akkor az eredménybıl is ilyen függvényt célszerő elıállítani, vagyis most a feladat egy digitális jelsorozatból egy folytonos függvény elıállítása, a digitál-analóg átalakítás (D/A konverzió). A legegyszerőbb esetben ez egy lépcsıs függvény, vagy a mintavett kvantált jeleknek megfelelı pontokat összekötı egyenesekbıl álló függvény, de lehet magasabb fokú polinomokkal is közelíteni a függvényt.
19
SZÁMÁBRÁZOLÁS Ebben a részben az adatoknak r szimbólummal való megadásával foglalkozunk. A számítógép véges sok, adott formátumú szimbólum feldolgozására képes, az elvi tárgyalás szempontjából – eltekintve a mőszaki kérdéseket – közömbös, hogy az egyes szimbólumok konkrét megjelenési formája milyen, ezért ha a gép r szimbólumot képes megkülönböztetni, ahol r egy 1-nél nagyobb egész szám, akkor feltehetjük, hogy ezek a szimbólumok az r-alapú számrendszer jegyei, vagyis a 0, 1, ..., r − 1 számot jelölı szimbólumok (ezek halmazát a továbbiakban N r -rel jelöljük). Amennyiben r nagyobb, mint tíz, akkor persze további jeleket kell alkalmaznunk. Mivel a számítástechnikában, mint majd szó lesz róla, a 16-os, úgynevezett hexadecimális számrendszer is elterjedt, ezért ilyenkor a decimális számjegyeken túl még 6 további jelre van szükségünk. Ezek a kialakult szokásnak megfelelıen az angol ábécé elsı hat betőjének nyomtatott nagybetős alakjai a természetes sorrendben, vagyis A = 10 , B = 11 , C = 12 , D = 13 , E = 14 , F = 15 . A számítástechnikában különösen régebben használatos további számrendszerhez, az oktálishoz nincs szükség a decimális jegyeken túl más szimbólumokra, ugyanis ez a 8-as számrendszer. A kettes számrendszerben felírt szám egy-egy jegye a bit, vagyis egy 0 vagy egy 1. A gépben az adatok fix hosszúságúak, vagy a hosszuk egy fix hosszúság néhány kis egész számszorosa. A régi gépekben ez a fix hosszúság különbözı volt, és általában egyetlen hosszúságot jelentett, így volt gép, amelyben az adatok 12 bitesek, míg más gépekben például 48 bitesek voltak. Az ilyen gépek szószervezésőek. A szó mérete általában a memóriából egyetlen lépésben kiolvasható adat hossza. A mai gépekben általában egynél több (de nem túl sok) különbözı hosszúságú adat manipulálható, és a hoszszúságok egy legrövidebb hossz többszörösei (elıfordul, hogy egyes gépek bizonyos utasításai változó hosszúságú adatokkal képesek dolgozni, ilyenkor például magában az utasításban adjuk meg a konkrét adat hosszát). A mai gépekben ez a legrövidebb hossz szinte kizárólag 8 bit, és egy ilyen legrövidebb hosszúságú adatot, tehát praktikusan a 8 bit hosszúságú adatot bájtnak (angolosan byte) nevezzük (a bájt hosszának okáról késıbb még lesz szó). A további elnevezések már nem egységesek: szokás a kétbájtos adatot félszónak, a négybájtosat szónak, míg a nyolcbájtosat duplaszónak nevezni, míg más helyen például a szó 16 bites adatot jelent. Azt az eljárást, amikor bizonyos adatokhoz az r-alapú számrendszer egyes értékeit hozzárendeljük, kódolásnak mondjuk. A kódolás pontosan azt jelenti, hogy a kódolandó elemek halmazát injektíven leképezzük egy halmazba. A képelemek halmaza a kód, a hozzárendelés a kódolás, és az u elemhez rendelt érték az u kódja. Az injektivitás nyilván szükséges követelmény a visszafejtéshez, vagyis a dekódoláshoz. (Léteznek nem injektív kódolások, ekkor természetesen nem lehet a kódból egyértelmően dekódolni. Az ilyen kódokat veszteséges kódnak mondjuk, míg az injektív kódolás veszteségmentes.) Az injektivitásból következik, hogy a kódolandó elemek száma nem lehet nagyobb a kód számosságánál. Ha az r-alapú számrendszerben felírt n-jegyő számokkal kódolunk, akkor a kódhalmaz összesen r n -elemő, vagyis egy kódolással legfeljebb ennyi különbözı dolgot tudunk kódolni. A legegyszerőbb kódolás, amikor egy legfeljebb 256-elemő halmaz elemeit a 256 különbözı bájtból álló halmaz elemeivel kódoljuk. A kódolandó halmaz ilyenkor általában az angol ábécé kis- és nagybetőit, a decimális számjegyeket, az írásjeleket és néhány egyszerő grafikus jelet, valamint speciális jeleket tartalmaz. Ilyen kódolásra több szabvány létezik, közülük legismertebb és leggyakrabban alkalmazott az IBM által kifejlesztett és használt EBCDIC (Extended Binary Coded Decimal Interchange Code=Kiterjesztett Binárisan Kódolt Decimális CsereKód), valamint az ASCII-kód (American Standard Code for Information Interchange=Amerikai Szabványos Kód InformációCseréhez). A széles körben használt személyi számítógépek általában az utóbbit használják. Ez a kód eredetileg 7-bites volt, majd úgy csináltak belıle 8-bites kódot, hogy az egyik bitet egyszerően megduplázták, illetve más esetekben egy paritásbittel egészítették ki (errıl a Hibakorlátozásnál lehet olvasni), végül újabb szimbólumokkal egészítették ki a kódolandó elemek halmazát. Az ilyen kódokat általában táblázattal adják meg, és ügyelnek rá, hogy a számjegyek illetve a betők kódjai az eredeti sorrendben, közvetlenül egymás utáni értékek legyenek. Ezekkel az adatokkal általában csak összehasonlítás végezhetı: mivel egy-egy bájt egy 256-nál kisebb nem negatív egész számnak tekinthetı, ezért ez a kódszavak egy lehetséges rendezését jelenti, de természetesen táblázatok segítségével bármilyen rendezés megadható,
SZÁMÁBRÁZOLÁS
20
és akkor vizsgálhatjuk, hogy például két kódszó közül melyik elızi meg a másikat. Magukkal a kódszavakkal mint számokkal természetesen bonyolultabb matematikai mőveletek is elvégezhetıek, ám ezeknek magukhoz a kódszavakhoz semmi közük sincs. Éppen ezért az ilyen kódokat alfabetikus illetve alfanumerikus kódnak nevezzük, amellyel azt fejezzük ki, hogy csupán betőket és írásjeleket, vagy az elıbbieken túl számokat is kódolunk, de nem mint számokat, hanem csak mint a számok grafikus jelét tekintve. Az EBCDIC és az ASCII kódok táblázata az 1.-5. Táblázatokban látható. Jelenleg egyre szélesebb körben alkalmazzák a Unicode-ot, legalábbis ennek bizonyos részkódjait. Ez a kód 46 hexadecimális jeggyel kódol, így igen nagy jelkészletet képes kódolni, például a különbözı írások írásjegyeit is. Néhány kiragadott példa: 0000 16 − 007 F16 0080 16 − 00 FF16 0100 16 − 017 F16 0370 16 − 03 FF16 0400 16 − 04 FF16 0600 16 − 06 FF16 3040 16 − 309 F16 30 A016 − 30 FF16 3100 16 − 312 F16 4 E 00 16 − 9 FBB16 10000 16 − 1007 F16 100000 16 − 10 FFFD16
a latin ábécé, a latin ábécé kiegészítése, ez a rész tartalmazza például a magyar ékezetes betőket, kivéve az ı, İ, ő és Ő karaktereket, amely a tartományban elhelyezkedı kiterjesztett latin-A kódok között található, a tartományban kódolják a görög és kopt ábécét, tartalmazza a cirill ábécét, az arab betőket, a hiragana, a katakana (az utóbbi kettı, közös néven a kana, a japán szótagírás), a bopomofo jelkészlet (a kínai nem latin ábécés fonetikus írása), tartalmazza a CJK-jelkészletet (Chinese/Japanese/Korean, azaz a kínai-japán-kóreai írásjeleket), a lineáris B (Kréta-szigeti régi írás), magánhasználatra szánt kiegészítı tartomány B része.
ACII-KÓDTÁBLÁZAT
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI
1 DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US
2 (sp) ! " # $ % & ' ( ) * + , . /
3 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
4 @ A B C D E F G H I J K L M N O
1. Táblázat
5 P Q R S T U V W X Y Z [ \ ] ^
6 ` a b c d e f g h i j k l m n o
7 p q r s t u v w x y z { | } ~ (del)
Számítógépi matematika
21
Például az 1. Táblázat 7-tel jelölt sorában és 4-gyel jelölt oszlopában álló nagy G bető 7 bites ASCII kódja 4716 . ASCII VEZÉRLİKARAKTEREK hex 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
jel NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US
vezérlı karakterek funkciója NULl Start Of Heading Start Of teXt End Of teXt End Of Transmission ENQiury ACKnowledge BELl BackSpace Horizontal Tab Line Feed Vertical Tab Form Feed Carriage Return Shift Out Shift In Data Link Escape Device Control 1 Device Control 2 Device Control 3 Device Control 4 Negative AcKnowledge SYNcronous idle End of Transmission Block CANcel End of Medium SUBstitute ESCape File Separator Group Separator Record Separator Unit Separator 2. Táblázat
A 4. és 5. Táblázatban (24. és 25. oldal) MSN a magasabb, míg LSN az alacsonyabb helyiértékő félbájt (MSN: Most Significant Nibble, azaz a legértékesebb félbájt, LSN: Least Significant Nibble, vagyis a legkevésbé értékes félbájt). Például a táblázat alapján m EBCDIC-kódja 9416 . A kódoláshoz számokat használunk, ezért ezekkel bármely, a számokon elvégezhetı mővelet végrehajtható. Ennek akkor van értelme, ha maguk a kódolandó adatok is numerikusak. Az ilyen kódokat numerikus kódnak nevezzük. A numerikus kódolásnak több változata ismeretes. Maga a numerikus adat független a megadási módjától, vagyis például 253 csak egy lehetséges kódja annak a számnak, amelyet mondjuk akkor kapunk, ha egy tálban 253 kavics van, és megszámoljuk a tálban lévı kavicsokat. Ugyanezt az információt megadhatjuk a CCLIII alakban is, feltéve, hogy aki olvassa, az tudja, hogy római számokkal adtuk meg a kavicsok számát. Éppen ezért az elsı kérdés, hogy hogyan lehet egy számot egy rögzített alapszámú számrendszerben felírni, illetve
SZÁMÁBRÁZOLÁS
22
vissza, ha adott egy számrendszer megadásával egy számjegysorozat, mely számnak felel ez meg. Ha meg tudjuk oldani az elıbbi két problémát, akkor végre tudjuk hajtani a számkonverziót is, ami nem más, mint egy számnak az egyik számrendszerben felírt alakjából egy másik számrendszerben megadott alakjának a meghatározása. KITERJESZTETT ASCII-KÓD
A táblázatban az adott karakter decimális kódja áll, ez nyolcbites kódként hexadecimálisan például í esetén azt jelenti, hogy ennek a karakternek a 8 bites ASCII kódja A116 . 3. Táblázat
Mivel a továbbiakban a számokat különbözı alapszámú számrendszerben írjuk fel, az alapszámot a szám jobb szélén süllyesztve jelöljük: 3892 11 tehát a 11-es számrendszerben felírt szám. Ha a félreértés veszélye nem fenyeget, akkor a kettes és a tízes számrendszert nem jelöljük. Egy szám kettes számrendszerbeli – másként bináris – felírásának jegyeit, a biteket, egész szám esetén kettıvel való ismételt maradékos osztással kapjuk, ahol a maradékok szolgáltatják, sorban egymás után, a legalacsonyabb helyiértékő, azaz a jobb szélsı jegytıl kezdve, a szám számjegyeit, és az osztást az aktuális hányados egész részével végezzük. Ha például százötvenhét bináris jegyeit akarjuk meghatározni, akkor a számolás a következıképpen alakul: 157 78 39 19 9 4 2 1
= = = = = = = =
78⋅2+1 39⋅2+0 19⋅2+1 9⋅2+1 4⋅2+1 2⋅2+0 1⋅2+0 0⋅2+1
157 78 39 19 9 4 2 1 0
1 0 1 1 1 0 0 1
157 78 39 19 9 4 2 1
1 0 1 1 1 0 0
Számítógépi matematika
23
A középsı oszlopnál az osztandóval egy sorba írtuk a maradékot, míg a jobb szélsı oszlopnál a hányadost és a maradékot írtuk egy sorba. Látható, hogy az utolsó osztást felesleges elvégezni, mert a hányados biztosan 0 és a maradék biztosan 1 lesz. A leolvasás mindkét esetben a nyíl mentén történik.
SZÁMÁBRÁZOLÁS
24
EBCDIC-KÓD 1. RÉSZ binary MSN LSN
0000
0001
0010
0011
0100
0101
0110
0111
0
1
2
3
4
5
6
7
hex
0000
0
NUL
0 16 DLE 00 10
0001
1
SOH
1 17 33 DC1 SOS 01 11 21
0010
2
STX
2 18 DC2 02 12
0011
3
ETX
3 19 TM 03 13
0100
4
PF
4 20 36 RES BYP 04 14 24
0101
5
HT
5 05
NL
21 15
0110
6
LC
6 06
0111
7
DEL
7 07
1000
8
8 24 CAN 08 18
40 28
1001
9
9 25 EM 09 19
1010
A
1011
B
VT
1100
C
1101
DS
32 20
48 64 SP 30 40
&
80 50
-
96 60
112 70
/
97 61
113 71
49 31
65 41
81 51
34 50 SYN 22 32
66 42
82 52
98 62
114 72
35 23
51 33
67 43
83 53
99 63
115 73
PN
52 34
68 44
84 54
100 64
116 74
37 25
RS
53 35
69 45
85 55
101 65
117 75
BS
22 38 ETB 16 26
UC
54 36
70 46
86 56
102 66
118 76
IL
23 39 55 ESC EOT 17 27 37
71 47
87 57
103 67
119 77
56 38
72 48
88 58
104 68
120 78
41 29
57 39
73 49
89 59
105 69
121 79
10 26 42 CC SM 0A 1A 2A
58 3A
FS
LF
¢ (cent)
74 4A
!
90 5A
3
106 6A
:
122 7A
11 27 43 59 CU1 CU2 CU3 0B 1B 2B 3B
.
75 4B
$
91 5B
,
107 6B
#
123 7B
FF
12 28 IFS 0C 1C
44 60 DC4 2C 3C
<
76 4C
*
92 5C
%
108 6C
@
124 7C
D
CR
13 29 45 61 IGS ENQ NAK 0D 1D 2D 3D
(
77 4D
)
93 5D
_
109 6D
'
125 7D
1110
E
SO
14 30 46 IRS ACK 0E 1E 2E
+
78 4E
;
94 5E
>
110 6E
=
126 7E
1111
F
SI
15 31 27 63 IUS BEL SUB 0F 1F 2F 3F
| 1 79 4F
¬
95 5F
?
111 6F
"
127 7F
SMM
4. Táblázat
62 3E
2
Számítógépi matematika
25
EBCDIC-KÓD 2. RÉSZ binary MSN LSN
1000
1001
1010
1011
1100
1101
1110
1111
8
9
A
B
C
D
E
F
hex
128 80
144 90
160 A0
176 B0
j
145 91
161 A1
177 B1
A
193 C1
130 82
k
146 92
s
162 A2
178 B2
B
c
131 83
l
147 93
t
163 A3
179 B3
4
d
132 84
m
148 94
u
164 A4
0101
5
e
133 85
n
149 95
v
0110
6
f
134 86
o
150 96
0111
7
g
135 87
p
1000
8
h
136 88
1001
9
i
137 89
1010
A
138 8A
154 9A
170 AA
186 BA
202 CA
218 DA
234 EA
250 FA
1011
B
139 8B
155 9B
171 AB
187 BB
203 CB
219 DB
235 EB
251 FB
1100
C
140 8C
156 9C
172 AC
188 BC
204 CC
220 DC
236 EC
252 FC
1101
D
141 8D
157 9D
173 AD
189 BD
205 CD
221 DD
237 ED
253 FD
1110
E
142 8E
158 9E
174 AE
190 BE
206 CE
222 DE
238 EE
254 FE
1111
F
143 8F
159 9F
175 AF
191 BF
207 CF
223 DF
111 6F
255 FF
0000
0
0001
1
a
129 81
0010
2
b
0011
3
0100
208 D0
224 E0
0
240 F0
J
209 D1
225 E1
1
241 F1
194 C2
K
210 D2
S
226 E2
2
242 F2
C
195 C3
L
211 D3
T
227 E3
3
243 F3
180 B4
D
196 C4
M
212 D4
U
228 E4
4
244 F4
165 A5
181 B5
E
197 C5
N
213 D5
V
229 E5
5
245 F5
w
166 A6
182 B6
F
198 C6
O
214 D6
W
230 E6
6
246 F6
151 97
x
167 A7
183 B7
G
199 C7
P
215 D7
X
231 E7
7
247 F7
q
152 98
y
168 A8
184 B8
H
200 C8
Q
216 D8
Y
232 E8
8
248 F8
r
153 99
z
169 A9
185 B9
I
201 C9
R
217 D9
Z
233 E9
9
249 F9
` 4
5. Táblázat
192 C0
26
SZÁMÁBRÁZOLÁS
Tört esetén kettıvel való ismételt szorzás egész részei a szám számjegyei, balról jobbra haladva, a szorzást a törtrésszel folytatva. Példaként kétszázhetvenhat ezred bináris jegyeit határozzuk meg: 0 0 1 0 0 0 1 1 0
2⋅0,276 = 0,552 = 0+0,552 2⋅0,552 = 1,104 = 1+0,104 2⋅0,104 = 0,208 = 0+0,208 2⋅0,208 = 0,416 = 0+0,416 2⋅0,416 = 0,832 = 0+0,832 2⋅0,832 = 1,664 = 1+0,664 2⋅0,664 = 1,328 = 1+0,328 2⋅0,328 = 0,656 = 0+0,656
276 552 104 208 416 832 664 328 656
vagyis 0,276 10 = 0,01000110 2 és 157 ,276 10 = 10011101,01000110 2 . Látszik, hogy a bináris alak nem pontosan adja az eredeti számot, hiszen a szorzások után nem nulla áll, ám egy véges decimális tört általában nem véges kettedes tört. A véges decimális tört akkor és csak akkor lesz véges hosszúságú a bináris számrendszerben, ha a szám felírható egy páratlan egész szám, valamint kettı egy pozitív egész kitevıs hatványának hányadosaként. Az egész rész és a törtrész jegyeinek meghatározását egyszerre is elvégezhetjük az egészeknél ismertetett módon, ha a számot a konverzió elvégzése elıtt megszorozzuk 2 m -mel, ahol m a bináris törtjegyek száma, az így kapott szám egészrészét mint egész számot konvertáljuk, és az eredményben a kettedes pontot m jeggyel balra mozgatjuk. Az elıbbi példát a fenti módon számolva m = 8 , 2 8 = 256 , 156,276 ⋅ 26 = 40262,656 , ennek az egész része 40262, és ezt konvertálva 40262 = 20131⋅2+0 20131 = 10065⋅2+1 10065 = 5032⋅2+1 5032 = 2516⋅2+0 2516 = 1258⋅2+0 1258 = 629⋅2+0 629 = 314⋅2+1 314 = 157⋅2+0 157 = 78⋅2+1 78 = 39⋅2+0 39 = 19⋅2+1 19 = 9⋅2+1 9= 4⋅2+1 4= 2⋅2+0 2= 1⋅2+0 1= 0⋅2+1
40262 20131 10065 5032 2516 1258 629 314 157 78 39 19 9 4 2 1
0 0 1 1 0 0 0 1 0 1 0 1 1 1 0 0
vagyis 40262 10 = 1001110101 000110 2 , és a bináris vesszıt nyolc hellyel balra mozdítva kapjuk, hogy nyolc bináris törtjeggyel számolva 157,27610 = 10011101,01000110 2 , egyezésben a korábban kapott eredménnyel. A kettes számrendszerben megadott szám jegyeinek ismeretében maga a szám a Hornermódszerrel határozható meg a legkönnyebben. Vegyük a szám bal szélsı jegyét, és ha már eljutottunk valameddig, akkor az addigi eredményt szorozzuk meg kettıvel, és az eredményhez adjuk hozzá a szám soron következı jegyét, balról jobbra haladva, majd, ha a szám törtrésze nem nulla, akkor az így kapott számot osszuk el 2-nek a törtjegyek számának megfelelı hatványával. Például az elıbbi szám visszaalakítása a következı:
Számítógépi matematika
2⋅1+0 2⋅2+0 2⋅4+1 2⋅9+1 2⋅19+1 2⋅39+0 2⋅78+1 2⋅157+0 2⋅314+1 2⋅629+0 2⋅1258+0 2⋅2516+0 2⋅5032+1 2⋅10065+1 2⋅20131+0
= = = = = = = = = = = = = = =
2 4 9 19 39 78 157 314 629 1258 2516 5032 10065 20131 40262
1 0 0 1 1 1 0 1 0 1 0 0 0 1 1 0
27
2 4 9 19 39 78 157 314 629 1258 2516 5032 10065 20131 40262
40262 40262 = = 157,2734375 . Mint látjuk, az egész rész pontos, ám a törtrész kisebb az eredeti 256 28 értéknél, ami érthetı, hiszen a decimálisból binárisba alakításnál a leálláskor még pozitív szám volt az algoritmusban. Figyelemre méltó ezen kívül, hogy véges hosszúságú bináris tört decimális megfelelıje mindig véges hosszúságú.
és
Az eljárás hasonló akkor is, ha a számrendszer alapszáma nem 2. Legyen például α = 5683 , és r = 17 . Ekkor ← 5683 = 334· 17 + 5
5683 334
5
←
19
B
←
1
2
334 = 19· 17 + 11 19 =
1· 17 + 2
vagyis 568310 = 12 B 517 (az utolsó osztást elhagytuk, hiszen egy 17-nél kisebb számot 17-tel osztva a hányados biztosan 0, és a maradék az osztandó; a leolvasás alulról felfelé, az utolsó hányadostól kezdve történik, vagyis ez lesz a legmagasabb helyiértékő számjegy). Ha 5683-at két jegyre kell meghatározni a 17-es számrendszerben, akkor az eredmény B 517 , és hibajelzést kapunk, ami jelzi, hogy ekkora hosszon nem lehet ábrázolni ezzel az alappal a megadott számot. Ha viszont az elıírt hossz 6 jegy, akkor 5683 felírása a 17-es számrendszerben 0012 B517 . Írjuk fel például 0,8672 -et az 5-ös illetve a 3-as számrendszerben. 0
8672
← 0,8672· 5 = 4,336
0
8672
← 0,8672· 3 = 2,6016
4
336
←
0,336· 5 = 1,68
2
6016
← 0,6016· 3 = 1,8048
1
68
←
0,68· 5 = 3,4
1
8048
← 0,8048· 3 = 2,4144
3
4
←
0,4· 5 = 2
2
4144
← 0,4144· 3 = 1,2432
2
0
1
2432
vagyis 0,8672 10 = 0,4132 5 . Hasonló számítással 0,867210 = 0, 30 1211 7 35 , ahol például 12 a 35-ös számrendszer 12-nek megfelelı számjegye. Nézzük ugyanezt a számot a 3-as számrendszerben. Észrevehetjük, hogy ennek a számításnak soha nem lesz vége, vagyis soha nem kapunk olyan eredményt, amelynek a törtrésze 0: az utolsó helyen álló számjegy sorban 2, 6, 8, 4 és 2, és ha most ismét 3-mal
SZÁMÁBRÁZOLÁS
28
szorzunk, akkor ezen a pozíción újra 6 jelenik meg. Azt látjuk, hogy egy számrendszerben véges hoszszúságú tört más számrendszerben végtelen hosszúságú. Kérdés, hogy egy szám mely számrendszerben adható meg véges sok jeggyel, és ha ez nem lehetséges, hány jegyre végezzük az átalakítást. Egy 1-nél kisebb pozitív racionális szám akkor és csak akkor írható fel az r-alapú számrendszerben véges sok jeggyel, ha felírható olyan törtként, amelynek a számlálója egész szám, és a nevezıje az r pozitív egész kitevıs hatványa. Az 1-nél kisebb pozitív valós szám pontosan akkor írható fel véges sok jeggyel az r-alapú számrendszerben, ha redukált tört alakú felírásának nevezıje olyan, amelynek valamennyi prímosztója egyben r-nek is osztója. Az elıbbi megállapításból rögtön következnek a példa eredményei: 8672 = 2 5 ⋅ 271 , és ebbıl 8672 2 5 ⋅ 271 542 0,8672 = = 4 4 = 4 . Mind 5, mind 35 osztható 5-tel, így az 5-ös és a 35-ös számrend10 4 2 ⋅5 5 szerben véges törtet kapunk, míg 3 nem osztható 5-tel, így 0,8672 nem lehet véges ternáris tört. Ez egy kicsit lehangoló: a számítástechnikában a 2-es számrendszert használjuk, így csak azok a törtek lesznek végesek, amelyek redukált tört alakú felírásában a nevezı 2-nek egy hatványa. A számítógéppel feldolgozandó adataink túlnyomó többsége véges tizedes tört, ám ezek nagy része nem véges a kettes számrendszerben, hiszen általában 5-tel is osztható a nevezıjük. A 10-es számrendszerben legfeljebb m jeggyel felírható valódi törtek száma 10 m − 1 , és ezek közül csupán 2 m − 1 véges kettedes tört, tehát körülbelül csak minden 5 m -edik tört ilyen tulajdonságú. Ugyanakkor egy véges kettedes tört biztosan véges hosszúságú a tízes számrendszerben is. A fenti eredmények alapján egy tört konverziója általában csak végtelen sok lépésben ad helyes eredményt, így el kell döntenünk, hogy mikor hagyjuk abba az átalakítást. Könnyő a válasz, amennyiben adott számú jeggyel kell megadni a számot. Ellenkezı esetben két megoldást ismertetünk. 1. Egy racionális szám felírása bármely alapszám esetén vagy véges, vagy ha nem, akkor egy ponttól kezdve periodikus. Ha például α = 0,17 és r = 6 , akkor 0
17
←
0,17· 6 = 1,02
1
02
←
0,02· 6 = 0,12
0
12
←
0,12· 6 = 0,72
0
72
←
0,72· 6 = 4,32
4
32
←
0,32· 6 = 1,92
1
92
←
0,92· 6 = 5,52
5
52
←
0,52· 6 = 3,12
3
12
és mivel 12 már volt, ezért onnan kezdve minden ismétlıdik, vagyis 0,1710 = 0,1004153 6 , ahol a 5 felülhúzott rész periodikusan ismétlıdik. Másik példaként írjuk fel α = -et a 6-os számrendszerben: 14
5 30 2 = =2+ 14 14 14 2 12 12 6⋅ = =0+ 14 14 14 12 72 2 6⋅ = =5+ 14 14 14
6⋅
Számítógépi matematika
29
5 = 0,205 6 , és a felülhúzás ismét a periodikusan ismétlıdı részt mutatja. Általában, ha az 14 elsı ismétlıdési pontig terjedı szakasz nem túlságosan hosszú (ez persze nem túl pontos megfogalmazás), akkor eddig érdemes az átalakítást végezni, és esetleg jelezni a periodicitást. vagyis
2. A második eljárás akkor célszerő, ha az átalakítandó szám egy mérés eredménye. Egy ilyen eredmény nem csupán mőszaki, de elvi okokból sem pontos. Amennyiben egy mérés eredményét úgy adják meg, hogy mondjuk 3,1400 ⋅ 10 −1 , akkor az azt jelenti, hogy az utolsó elıtti helyen álló 0 még pontos érték, és az utolsó 0 a valódi értéktıl legfeljebb egy egységgel tér el, vagyis a pontos érték 3,1400 ⋅ 10 −1 és 3,1401⋅ 10 −1 között van, tehát a bizonytalanság mértéke 0,0001 ⋅ 10 −1 = 10 −5 . Ha ezt a mérési eredményt a kettes számrendszerben kell megadnunk, akkor annyi jegyre számolunk, hogy az átalakított szám utolsó jegyének egységnyi változása az elıbbi bizonytalansággal megegyezı nagyságrendő eltérést eredményezzen. Legyen a k-adik törtjegy az utolsó a bináris felírásban. Ekkor 2 − k ≤ 10 −5 < 2 − (k −1) , és innen k − 1 < 5 log 2 10 ≤ k , vagyis k = 5 log 2 10 = 5 ⋅ 3,32 = 17 , tehát 0,314 -et most 17 bináris törtjeggyel kell megadni: 0,31400 10 = 0,0101000001 1000100 2 . Lényeges megjegyezni, hogy ha egy decimális törtet binárisba alakítunk, és a decimális tört jegyeinek száma k, akkor a bináris tört jegyeinek száma 3,32 ⋅ k . Végül még egy kérdést kell tisztáznunk. Az egész számok konverziójánál láttuk, hogy a szám jegyei bármely számrendszerben egyértelmően meghatározottak. Kérdés, hogy ez igaz-e törtek esetén is. Egy valódi törtnek akkor és csak akkor nem egyértelmő a felírása az r-alapú számrendszerben, ha felírható véges r-edes törtként, és ekkor pontosan egy, az elıbbitıl eltérı felírása van ebben a számrendszerben, amelyet úgy kapunk, hogy a véges felírásban utolsó pozícióban álló nem nulla jegyet eggyel csökkentjük, és utána valamennyi (tehát végtelen sok) pozícióba r − 1 -et írunk. Például 0,2545 7 = 0,25446 7 . Az elıbbiekben meghatároztuk egy nem negatív valós szám számjegyeit egy adott alapszámú számrendszerben, nézzük most a másik irányt. Nézzünk egy példát: határozzuk meg α-t, ha α = 53 A412 . Ekkor r = 12 , n = 4 , a 3 = 5 , a 2 = 3 , a1 = 10 és a 0 = 4 . Innen
α (0 ) = α
(1)
α
(2 )
=α
a3 = (0 )
r + a2 =
5 5 ⋅ 12 + 3 =
63
(1)
= α r + a1 = 63 ⋅ 12 + 10 = 766
α (3) = α (2 ) r + a 0 = 766 ⋅ 12 + 4 = 9196 = α Egyszerő és könnyen áttekinthetı a következı elrendezés (valójában az 5 x 3 + 3x 2 + 10 x + 4 polinom 12-nél vett helyettesítési értékének kiszámítása az úgynevezett Horner-módszerrel): 5 12
3 5
10 4 63 766 ↑ 5 ⋅ 12 + 3
9196
Az elıbbi számítást felírhatjuk ((5 ⋅ 12 + 3) ⋅ 12 + 10 ) ⋅ 12 + 4 alakban. Innen látjuk, hogy 5-öt háromszor szoroztuk 12-vel, 3-at kétszer, 10-et egyszer és 4-et egyszer sem, és ezeket a részeredményeket adtuk össze. Általános esetben is α (n −1) = (K (a n −1 r + a n − 2 ) ⋅ r + K + a1 ) ⋅ r + a 0 , vagyis a n −1 -et az n − 1 -tıl 1-ig terjedı indexek mindegyikénél megszorozzuk r-rel, vagyis összesen r n −1 -gyel, és
SZÁMÁBRÁZOLÁS
30
minden további számjegyet sorban eggyel kevesebbszer, tehát a k -t éppen r k -val, és az így kapott szorzatokat összeadjuk, ami valóban a jó eredmény. n −1
Nézzük meg, hogy hány mőveletre van szükség α = ∑i =0 ai r i kiszámításához. Az algoritmus elsı lépése egy értékadás, és minden további lépésben egy szorzásra és legfeljebb egy összeadásra van szükség, ahol a lépések száma összesen n − 1 , így az algoritmus végrehajtása során n − 1 szorzást és maximum n − 1 összeadást végzünk. Ha nagyon akarjuk, megtehetjük, hogy amennyiben a n −1 = 1 , akkor az elsı szorzás helyett egy értékadást végzünk, és ekkor a szorzások száma n − 2 lesz. −1
A fentiek alapján ha α = ∑i = − m ai r i = ∑i =1 bi r −i , vagyis valódi tört, akkor az α (0 ) = bm , m
m > k ∈ N + : α (k ) = α (k −1) r −1 + bm − k algoritmussal α = α ( m −1) r −1 . Legyen például α = 0,5204 6 , ekkor
4 +0 4 6 +2 +2 76 6 + 5 36 +5 +5 1156 6 6 216 , α= = = = 6 6 6 1296 vagyis 0,8919 ≤ α < 0,892 (már tudjuk, hogy a 10-es számrendszerben α nem lehet véges, ugyanis 1156 289 = , a jobb oldali számláló és nevezı relatív prím, és a nevezı osztható 3-mal, míg 10 nem). 1296 324 Egy törtrészt is tartalmazó szám értékének meghatározását más módon is elvégezhetjük. Len −1
n −1
n + m −1
gyen α = ∑i = − m ai r i , ekkor α = ∑i = − m ai r i = r − m ∑i =0
ai − m r i = r − m u , ahol u már egész szám.
Ekkor meghatározhatjuk u-t a Horner-módszerrel, és az eredményt elosztva r m -mel megkapjukα-t. 8313 Legyen például α = 2312,23 5 , ekkor α = 5 − 2 (((((2 ⋅ 5 + 3)5 + 1)5 + 2)5 + 2)5 + 3) = . 25 Eddigi ismereteink alapján könnyen meg tudjuk adni α = 32 B5,02113 7-es számrendszerben való felírását. Ehhez elıször kiszámítjuk α-t, majd a szám 7-es számrendszerbeli jegyeit:
1 +2 13 +0 27 13 α = ((3 ⋅ 13 + 2) ⋅ 13 + 11) ⋅ 13 + 5 + = 7077 13 2197 7077 1011 144 20 2
0 3 4 6
Számítógépi matematika 27 2197 189 7⋅ 2197 1323 7⋅ 2197 473 7⋅ 2197 7⋅
31
189 189 =0+ 2197 2197 1323 1323 = =0+ 2197 2197 9261 473 = =4+ 2197 2197 3311 1114 = =1+ 2197 2197
=
így 32 B5,02113 = α = 26430,00417 . Természetesen α a 7-es számrendszerben végtelen hosszúságú tört, ugyanis 27 és 2197 relatív prím, és 2197 nem hatványa 7-nek. Azért számoltunk négy törtjegyet, mert α 13-as számrendszerben megadott alakjában a törtjegyek száma 3, és 3 log 7 13 = 4 . A fenti példában elıször átírtuk α-t a tízes számrendszerbe, majd onnan a 7-esbe. Bizonyos esetekben az átalakítás könnyebben is elvégezhetı. A számítástechnikában elterjedten használják a kettes számrendszer mellett a tizenhatos, vagy másként hexadecimális számrendszert. Mivel ebben a számrendszerben 16 számjegyre van szükség, ezért hat újabb számjegyet kell bevezetni az ismert decimális jegyeken túl. Ezeket a jegyeket sorban az angol ábécé elsı hat betőjének nagybetős alakja jelöli, tehát A, B, C, D, E és F a 10, 11, 12, 13, 14 és 15 hexadecimális jele. A decimálisból hexadecimálisba való átszámítás pontosan úgy történik, mint a kettes számrendszerbe való konverzió, és a visszaalakítás is azonos, amint a következı példa mutatja: 157=9⋅16+13 9=0⋅16+ 9 16⋅0,276=4,416=4+0,416 16⋅0,416=6,656=6+0,656 16⋅0,656=10,496=10+0,496
157 9 0 0 4 6 A
D 9 276 416 656 496
tehát 157,27610 = 9 D,46 A16 , ahol az egyenlıség persze csak abban az értelemben igaz, hogy a számot három hexadecimális törtjegyig számoljuk. Visszaszámolva
1 16 3
((((9 ⋅ 16 + 13)16 + 4)16 + 6)16 + 10) = 644202 = 157,2758789K10
4096 276 69 ami ismét nem a pontos eredeti érték, ugyanis 0,27610 = = , ahol a számláló és a nevezı már 1000 250 relatív prím, és a nevezı nem 2-hatvány. A hexadecimális számrendszer csak segédeszköz, amelyet azért használunk, mert a gép binárisan dolgozik, ám egy decimális szám bináris felírásához körülbelül 3,32-szor annyi jegyre van szükség, mint a megszokott decimális felírásban, ugyanakkor a bináris - hexadecimális és hexadecimális bináris konverzió igen könnyen elvégezhetı. Ennek az az alapja, hogy 16 = 2 4 , és ennek következtében négy bit megad egy és csak egy hexadecimális számjegyet, és fordítva, minden hexadecimális számjegy felírható négy bit segítségével. Ebbıl adódik, hogy egy hexadecimális számot úgy alakíthatunk át binárissá, hogy minden hexadecimális számjegyet helyettesítünk az ı négybites bináris megfelelıjével, és az így kapott tetrádokat egymás mellé írjuk az eredeti sorrendnek megfelelıen, és az esetleges bináris vesszıt is a hexadecimális szám jobb szélsı egész és bal szélsı tört jegyének tetrádja közé helyezzük. A másik irányban viszont a kettedes vesszıtıl jobbra és balra négy-négy bitet össze-
SZÁMÁBRÁZOLÁS
32
fogunk egy-egy tetráddá, és a tetrádoknak megfelelı hexadecimális jeggyel helyettesítjük az egybekapcsolt négy bitet (a négyes csoportosítás megkívánhatja, hogy a szám jobb és bal szélén a hiányos bitcsoportot megfelelı számú nullával egészítsük ki). Az elıbbi hexadecimális számmal például 9 D,46 A16 = 1001 1101,0100 0110 1010 2 , és 101101,011111 2 = 0010 1101,0111 1100 2 = 2 D,7C16 . Általánosabban nézve, ha r2 = r1u , akkor az r2 alapú számrendszerben felírt számból úgy kapjuk meg ennek a számnak az r1 alapú számrendszerben felírt alakját, hogy mindenegyes számjegy helyére beírjuk az adott számjegy r1 alapú számrendszerbeli felírását. Ha például 011, 000 212 (a felülhúzott számjegysorozat egy 27-es számrendszerα = 12 4, 0 23 27 , akkor α = 110 {{ {{ 3 123
43
03
233
beli számot jelöl). Mivel az elıbb megadott egyenletsor visszafelé is igaz, ezért hasonlóan könnyő az r1 alapú számrendszerben felírt szám r2 = r1u alapú számrendszerbe való konvertálása: egyszerően az r1 edes vesszıtıl jobbra és balra a jegyeket u hosszúságú csoportba győjtjük (a két végén esetleg 0kkal kiegészítve), és egy-egy ilyen csoportot helyettesítjük a neki megfelelı számmal, amely így biztosan eleme N r2 -nek, tehát az r2 alapú számrendszer egy számjegye. Ha például α = 52041,312 6 ,
41, 31 20 6 = 512 25, 1912 36 . akkor 52041,312 6 = 05 { 20 {{ {{ ↓ ↓ ↓ ↓ ↓ 5 12 25 19 12
A számítástechnikában a bináris számrendszer mellett fontos a hexadecimális, vagyis a 16-os számrendszer is. Ennek az az oka, hogy a bináris számok viszonylag hosszúak: mint láttuk, körülbelül 3,3-szer akkora egy szám bináris alakjának hossza, mint a decimális, míg a hexadecimális inkább valamivel kisebb ( log 16 10 = 0,83 ), és fentebb láttuk, hogy az átírás binárisból hexadecimálisba és vissza igen könnyő. Ez azt jelenti, hogy a gép bináris adatokkal dolgozik, de a nyomtatott formában megjelenı adatok általában a bináris szám hexadecimális megfelelıjét tartalmazzák. 16 = 2 4 , ezért négy bináris számjegyet, egy úgynevezett tetrádot írunk át egy hexadecimális számjegybe, illetve fordítva, a hexadecimális felírás egyes jegyeit egy-egy bináris tetráddal helyettesítjük: 101101,1012 = 2 D, A16 , illetve BA1C ,3D16 = 1011101000 011100 ,00111101 2 . Régebben a hexadecimális rendszer helyett az oktálisat, azaz a 8-as alapút használták, ekkor a bináris számok hármas csoportját, egy-egy triádot alakítjuk át egyetlen oktális jeggyé, illetve visszafelé minden oktális számjegyet egy három bitbıl álló triáddá írunk át: 11010 ,012 = 32,2 8 és 72,54 8 = 111010,101100 2 = 111010,10112 . Míg a hexadecimális szám csak segédeszköz, addig a BCD-szám fontos ábrázolási mód a számítógépekben. Ezt az alakot akkor érdemes alkalmazni, amikor sok azonos nagyságrendő számmal végzünk viszonylag egyszerő, és kevés (mármint egy-egy adatra jutóan kevés) számítást. Különösen adatfeldolgozási rendszerekben gyakran fordul elı, hogy igen sok adattal kell igen kevés és egyszerő mőveletet elvégezni. Egy egyszerő példa, amikor népszámlálásnál a lakosság átlagéletkorát határozzuk meg: össze kell adni körülbelül 10 000 000 pozitív egész számot, és az összeget el kell osztani az adatok számával. A számítógép bináris számokkal dolgozik, elıször valamennyi adatot át kell alakítani bináris számmá, majd elvégezni az átlagolást, és utána az eredményt visszaalakítani decimális számmá. De egy szám binárisba konvertálása az összeadáshoz képest igen hosszú mővelet, így célszerőbb lenne közvetlenül a decimális számokkal végezni a mőveletet. Ugyanakkor tudjuk, hogy a biztonságos mőködés leginkább a kétállapotú eszközökkel, tehát a kettes számrendszer alkalmazásával biztosítható, és ennek megfelelıen a számítógép a kettes számrendszerben dolgozik. A kérdés az, hogy nem lehet-e a két szempontot egyidejőleg figyelembe venni. A konkrét kérdés úgy oldható meg, hogy a decimális szám számjegyeit adjuk meg binárisan, így maga a szám decimális, csupán a számjegyek megadása változik. Tekintettel arra, hogy a decimális számrendszerben tíz számjegy van, és három bittel csak a 0 és 7 közötti számok adhatóak meg (beleértve a 0-t és a 7-et is), ezért három bit kevés egy-egy decimális jegy megadásához. Ugyanakkor már láttuk, hogy négy bittel 16 különbözı érték
Számítógépi matematika
33
kódolható, ezért a BCD-számábrázolásnál mindenegyes decimális jegyet a neki megfelelı négybites bináris számmal helyettesítünk. Az így kapott bitsorozat lesz a decimális szám BCD-kódja. Pédául 176,9410 BCD-kódja 0001 0111 0110,1001 0100 BCD . Lényeges, hogy itt most nem hagyható el a szám jobb és bal szélén álló három illetve két 0, míg egy tisztán bináris szám esetén ezek a nullák értéktelen jegyek, és így nem szükséges a leírásuk. n −1
Általánosítva a problémát, legyen α = ∑i = − m ai r2i , és r1 valamint u olyan pozitív egész, hogy r1u ≥ r2 . Mivel valamennyi i-re 0 ≤ a i < r2 ≤ r1u , ezért valamennyi a i felírható u jeggyel az r1 alapú
számrendszerben, és ha a i = ∑ j = 0 a (ji ) r1 j , akkor α = ∑i = − m a i r2i = ∑i = − m u −1
n −1
n −1
(∑
u −1 j =0
) )
a (ji ) r1 j r2i . Ez az α r2
-alapú felírása, tehát a mőveleteket ennek megfelelıen kell végezni, de a számjegyeken az r1 számrendszerbeli mőveletek érvényesek. Legyen például r2 = 15 és r1 = 3 . Ekkor u legalább 3, legyen most 4. Ezekkel az adatokkal CA1B, D 215 = (01103 01013 00013 01023 ,01113 00023 )15 . A legfontosabb esetben r2 = 10 és r1 = 2 , ekkor u ≥ 4 . A gyakorlatban u értéke mindig 4, vagyis egy-egy decimális számjegyet egy-egy bináris tetráddal helyettesítünk. Az ilyen felírást fentebb BCD-kódnak neveztük (BCD a Binary Coded Decimal kifejezés rövidítése, vagy magyarul binárisan kódolt decimális). Például az 1849,74 decimális szám BCD-kódja 0001 1000 0100 1001,0111 0100 . Mivel mind a hexadecimális, mind a BCD-kód esetén egy-egy bináris tetrád jelent egy-egy számjegyet, ezért nagyfokú a hasonlóság. Lényeges különbség azonban, hogy bármely bináris tetrád érvényes hexadecimális számjegyet reprezentál, ezzel szemben a 9-nél nagyobb számot jelölı tetrádok nem jelentenek BCD-számjegyet. Ezek szerint 1000 0011 0000,1001 0010 akár BCD, akár hexadecimális szám lehet, míg 1010,0001 biztosan egy hexadecimális szám bináris felírása. Még belátjuk, hogy ha r1u ≥ r2 , akkor az α pozitív egész szám r1 -alapú felírása legfeljebb olyan hosszú, mint ha az r2 -alapú felírás jegyeit az r1 -alapú számrendszerben írjuk fel. Legyen n1 az r1 -alapú felírás hossza, és n2 az r2 -alapú felírás hossza. Ekkor n1 = log r1 α + 1 , n 2 = log r2 α + 1 , és a vegyes felírás hossza un 2 . De
(
)
n1 = log r1 α + 1 = log r1 r2 ⋅ log r2 α + 1 ≤ u log r2 α + 1 < u log r2 α + 1 + 1 = un 2 + 1 ,
tehát n1 < un 2 + 1 . Mivel mindkét oldalon egész szám áll, ezért ez megegyezik az n1 ≤ un 2 relációval. Például egy szám bináris felírása kb. 3,32-szer olyan hosszú, mint a decimális, míg a BCD-felírás az eredeti hossz négyszerese. Az EBCDIC kód a BCD-kód kiterjesztése: a decimális számjegyek kódja olyan bájt, amelynek alsó tetrádja a szám BCD-kódja, a kód numerikus része, míg a felsı tetrád F16 , a szám zóna része. Ez a hely alkalmas arra, hogy magyarázatot adjunk arra, miért éppen 8 bit alkot egy bájtot. Egy bájtban éppen két hexadecimális számjegy és pontosan két BCD-jegy fér el, ezen kívül egy bájttal 256 különbözı dolgot lehet kódolni. Ez a nagyság kényelmes: az angol ábécé 26 nagy- és 26 kisbetője, a 10 decimális számjegy, valamint a legszükségesebb írásjelek száma eleve meghaladja a 64-et, tehát 7 bitre mindenképpen szükség van, és a megduplázódott kódtérben egyéb elemeket, mint például ékezetes betőket lehet elhelyezni. Most rátérünk a numerikus adatok kódolására. A továbbiakban feltesszük, hogy a gép r szimbólumot kezel (ahol a valóságban r = 2 ), és az adatok hossza n, és így az egy kóddal megadható elemek száma legfeljebb r n . Az N szám kódját ϕ ( N ) -nel jelöljük, és ϕ ( N ) -et mindig egy r n -nél kisebb nem negatív egész számnak tekintjük. Az alábbiakban több különbözı kódot ismertetünk. Nézzük elıször, hogy milyen elvárásaink vannak egy kódtól: a. legyen egyszerő a kódolás és a dekódolás;
SZÁMÁBRÁZOLÁS
34 b. c. d. e. f. g. h. i.
minél több adatot kódoljunk; legyen egyszerő a mőveletvégzés; szomszédos kódolható számok kódja legyen szomszédos; a kódolt adatok eloszlása legyen egyenletes; a kódolandó számok halmaza minél nagyobb intervallumot fedjen le; szomszédos kódolandó számok távolsága legyen minél kisebb; a kódolás hibája legyen minél kisebb; a negatív és nem negatív számok kódja legyen könnyen megkülönböztethetı.
A megadott feltételek között vannak olyanok, amelyeket nem lehet egyszerre maradéktalanul kielégíteni, ilyenkor a konkrét igénynek legjobban megfelelı kódot kell alkalmazni. A minél több adat kódolása könnyen megvalósítható: annyi különbözı adatot kódolunk, amennyit csak lehet, vagyis összesen r n elembıl áll a kódolandó halmaz. Elsıként tegyük fel, hogy csak nem negatív számokat kódolunk, ez az elıjel nélküli számábrázolás. A legegyszerőbb megoldás az, ha ϕ (N ) = r m N , ahol N nem negatív egész, míg m egész szám. Mivel r n > ϕ (N ) ∈ N , és ∆ (ϕ ( N )) = 1 , vagyis két szomszédos kódszó távolsága 1, ezért az ábrázolható
(
)
számtartomány a kr − m számokból áll, ahol k egész szám. 0 ≤ k < r n , ϕ kr − m = k , a legkisebb, nullától különbözı kódnak, tehát az 1-nek megfelelı szám r − m , a legnagyobb kód, azaz r n − 1 , az r n − m − r − m szám kódja, és az egymás után következı kódok az egymástól r − m távolságra lévı számoknak felelnek meg. Ezek szerint ha az α valós számra 0 ≤ kr − m ≤ α < (k + 1)r − m < r n − m , akkor α-t egy 0 ≤ α − kr − m < r − m hibával tudjuk ábrázolni, vagyis az abszolút hiba maximális értéke r − m . Az abszolút hiba mellett fontos a relatív hiba is, hiszen 1 mm-es tévedés mást jelent a Föld és a Hold táα − kr − m volságának mérésekor, mint egy hangya hosszának megadásánál. A relatív hibát adja, felα α − kr − m 1 − m téve, hogy α nem nulla. De 0 ≤ α − kr − m < r − m , így 0 ≤ < r , ezért a kis számok kódoláα α sánál a relatív hiba maximuma nagyobb, mint a nagy számoknál. Ha α = kr − m , akkor mind az abszolút, mind a relatív hiba 0, és ha α balról közelít (k + 1)r − m -hez, akkor az abszolút hiba r − m -hez, míg a 1 relatív hiba -hez tart. Ez k növekedésével csökken, k = 0 , tehát α ≈ r − m esetén 1, a relatív hiba k +1 1 1 100%, míg a felsı határnál, vagyis amikor r n − m − r − m < α ≈ r n − m , = n = r − n , és a relak +1 r −1 +1
(
)
−n
tív hiba 100 r % . Ha például r = 2 és n = 16 , akkor a relatív hiba a kód felsı végénél legfeljebb 100 ⋅ 2 −16 = 0,0015% . Rögzített r, n és m esetén a kódolt számok megfelelı kód
n −1
n −1− m
∑i =− m
a i r i alakúak, és a
n −1− m
∑i =− m
a i r i számnak
n −1
∑i=0 ai−m r i = ∑i =0 bi r i . A kódolt érték egy n-jegyő egész szám az r-alapú számrend-
szerben, amelybıl az eredeti értéket úgy kapjuk meg, hogy az r-edes pontot a szám jobb szélétıl m pozícióval (elıjelesen) balra visszük, vagyis ha m negatív, akkor valójában az r-edes pont − m hellyel jobbra mozdul. Ez azt jelenti, hogy az r-edes pont helye az eredeti számban a kódszó jobb széléhez képest egy fix helyen van, ezért az ilyen számábrázolást fixpontosnak mondjuk. Nézzük meg, hogy különbözı m értékek mellett hogyan helyezkedik el az r-edespont. 1. m = 0 : ekkor az ábrázolt szám egész szám, és az r-edespont a kódszó jobb szélén áll:
Számítógépi matematika
…
bn−1
35
b0 ↑
2. m = n : ekkor az ábrázolt szám valódi tört, és az r-edespont a kódszó bal szélén áll: …
bn−1
b0
↑
3. m = n − 1 : ekkor az ábrázolt szám egy egész jegyet és n − 1 tört jegyet tartalmaz, és az redespont a kódszó bal szélétıl egy pozícióval jobbra áll: …
bn−1
b0
↑
4. m > n : ekkor az ábrázolt szám valódi tört, és az r-edespont a kódszó bal szélétıl m − n pozícióval balra áll, vagyis az r-edespont után legalább m − n pozícióban 0 áll: bm−1
…
bn−1
…
b0
↑
5. m < 0 : ekkor az ábrázolt szám egész szám, és az r-edespont a kódszó jobb szélétıl m pozícióval jobbra áll, vagyis a szám végén legalább m darab 0 áll: bn−1
…
b0
bm ↑
Ezek közül a valóságban 1., 2. és 3. fordul elı. Az 1. ábrázolás neve fixpontos egész, míg 2.-é fixpontos tört ábrázolás. Bármilyen is legyen a gépi megoldás, ha szükséges, úgy bármely más megoldás elérhetı szoftveres támogatással. Ekkor a program veszi figyelembe a szükséges eltolásokat. A késıbbiek kedvéért nézzük még meg, hogy mi lesz egy tetszıleges nem negatív α valós szám kódja az elıbbiek alapján, vagyis abban az esetben, amikor a számokat az r-alapú számrendszerben n jeggyel ábrázoljuk, és az ábrázolásban az r-edespont a kód jobb szélétıl balra számított m-edik jegy bal oldalán helyezkedik el (ahol ismét lehetséges, hogy m negatív, vagy n-nél nagyobb). Két dolgot kell tekintetbe vennünk. Egyrészt a számok túlnyomó többségénél szükség van m-nél kisebb kitevıs hatványokra, másrészt szintén a legtöbb szám esetén az n-nél nem kisebb hatványok is elıfordulnak. Ez azt jelenti, hogy az ilyen esetekben a szám pontos felírásához képest a kód alul vagy felül (vagy akár mindkét oldalon) csonkol. Az α valós szám kódja most ϕ (α ) = ( r mα mod r n ) lesz. Az elıjel nélküli számok fixpontos kódolása kielégíti az a., b., d. és e. feltételeket. A c. pontról majd csak a mőveletvégzéssel kapcsolatos problémák megbeszélésénél tudunk megállapítást tenni, f. nagysága n-tıl, míg g.-é m-tıl függ. Azt már korábban láttuk, hogy az abszolút hiba maximuma a teljes ábrázolt számtartományban állandó, míg a relatív hiba az adat értékének növekedésével hiperbolikusan csökken, vagyis kis értékő adatok esetén a relatív hiba maximuma nagy, így az ilyenek kódolása nagy relatív hibával jár. Ennek a problémának a kiküszöbölésérıl késıbb lesz szó. Az i.-beli problémának ennél a kódolásnál nincs értelme.
SZÁMÁBRÁZOLÁS
36
Áttérünk az elıjeles számok ábrázolására. Elsıként ismét a bináris esetet vizsgáljuk. A fixpontos számok elıjel-ábrázolásának legegyszerőbb módja az eltolt nullpontú számábrázolás. Ha a számot n bittel ábrázoljuk, akkor ennél az ábrázolási módnál az ábrázolandó számhoz hozzáadunk 2 n −1 -et vagy 2 n −1 − 1 -et (sajnos mindkét érték elıfordul a számítógépekben, ám egy adott gépnél ez csak az egyik érték). Az ábrázolható számtartomány az elsı esetben − 2 n −1 ≤ N ≤ 2 n −1 − 1 , míg a másodikban − 2 n −1 − 1 ≤ N ≤ 2 n −1 . Emlékeztetünk rá, hogy a fixpontos számok általában egész számok, így most is ezt tételeztük fel. Amennyiben a gép egy fixpontos számot nem egész számnak tekint, és ez lesz majd késıbb a helyzet a lebegıpontos számoknál, akkor annyi a változás, hogy a határértékeket el kell osztani 2 m -mel, ahol m a törtjegyek száma. Ugyanakkor az is tény, hogy az eltolt nullponttal megadott számok mindig egész számok lesznek. Ez a számábrázolási mód igen egyszerő, de a legfontosabb tulajdonsága a rendezéstartás, ami azt jelenti, hogy ennél a számábrázolási módnál, és csak ennél, kisebb szám kódja kisebb, ami nyilvánvaló, hiszen két szám nagyságrendi viszonyát nem befolyásolja, ha mindkettıhöz ugyanazt a számot hozzáadjuk. Példaként − 52 8-bites eltolt nullpontú kódja, ha az eltolás értéke 2 8−1 = 2 7 = 128 , (− 52 + 128 )10 = 7610 = 01001100 2 = 4C16 , míg 52
(
)
kódja a 2 8−1 − 1 = 127 -tel való eltolás esetén (52 + 127 )10 = 17910 = 10110011 2 = B316 . A 0 kódja az elıbbi esetben 10000000 2 = 8016 , és a második esetben 01111111 2 = 7 F16 . A legkisebb kódolható szám a 128 -cal való eltolás esetén − 128 , és ennek kódja 00000000 2 = 0016 , a legnagyobb kódolható szám és kódja 127, illetve 11111111 2 = FF16 . Ugyanezek az értékek a másik eltolás esetén a − 127 a 00000000 2 = 0016 kóddal, és 128 az 11111111 2 = FF16 kóddal. Az elıjel megadásának legtermészetesebb módja az elıjeles-abszolút értékes kód, amely a hétköznapi életben használt ábrázolási mód, hiszen a valóságban is úgy adjuk meg az elıjeles számokat, hogy az abszolút értékük elıtt elhelyezzük az elıjelüket (illetve nem negatív szám esetén az elıjelet elhagyhatjuk, és általában el is hagyjuk, de ezt a gépi ábrázolásnál nem tehetjük meg). Most az nbites ábrázolásnál a kód bal szélsı bitje jelzi a szám elıjelét: ha ez a bit 0, akkor a szám nem negatív, míg ha 1, akkor a kódolt szám negatív, és a többi n − 1 biten ábrázoljuk a szám abszolút értékének bináris kódját. Ismét a nyolcbites esetet nézzük. Ekkor a − 52 kódja 10110100 2 = B 416 , és az 52 kódja 00110100 2 = 3416 . Látjuk, hogy most a két kód bináris alakja csak a bal szélsı bitben különbözik. 0
(
)
kódja 00000000 2 = 0016 , a legkisebb ábrázolható szám − 2 7 − 1 = −127 , ennek 11111111 2 = FF16 a kódja, és a legnagyobb megadható szám 127, amelynek a kódja 01111111 2 = 7 F16 . A kódolási szabály alkalmazásával kapjuk, hogy az 10000000 2 = 8016 kódhoz tartozó szám eredeti értéke − 0 , ami a számítástechnikában a negatív nulla (szándékosan a nullát nem kódoljuk ezzel az alakkal, de a számítások során kialakulhat). A negatív nulla következtében a nullának két kódja van, és ez okozza, hogy ebben a számábrázolási módban eggyel kevesebb szám kódolható, mint az eltolt nullpontú kódban. Ez a számábrázolási mód nem rendezéstartó, hiszen bármely nem negatív szám kódja kisebb valamennyi negatív szám kódjánál, és kisebb negatív szám kódja nagyobb, mint egy nagyobb negatív számé. Egy harmadik problémája ennek a számábrázolási módnak, hogy nehézkes az ilyen módon kódolt számok összeadása és kivonása. Az elıbbiekben láttuk, hogy negatív szám kódja 1-gyel, pozitív szám kódja 0-val kezdıdik, így a legmagasabb helyiértékő jegy mutatja a szám elıjelét, ezért ezt a bitet elıjelbitnek nevezzük. A fixpontos számok elıjelének harmadik megadási módja a komplemens kód. Egy nem negatív szám komplemens kódja önmaga, míg az N negatív szám n-bites komplemens kódja a 2 n − N szám n-bites kódja. Az ábrázolható számtartomány − 2 n −1 ≤ N ≤ 2 n −1 − 1 , így abban az esetben, ha a szám negatív, akkor 2 n −1 ≤ 2 n − N ≤ 2 n − 1 , ami azt jelenti, hogy negatív szám kódja 1-gyel, míg pozitív szám kódja 0-val kezdıdik, hasonlóan az elıjeles-abszolút értékes számábrázoláshoz (de most nincs negatív 0, így a nulla kódja is mindig 0-val kezdıdik). Lényeges különbség azonban, hogy az elıjeles abszolút értékes ábrázolási módnál a szám abszolút értéke független az elıjeltıl, vagyis a kód
Számítógépi matematika
37
bal szélsı bitjétıl, így a számolásoknál az elıjelbit különválasztható a többi bittıl, ám ezt nem tehetjük meg a komplemens kód esetén, ezért ebben az esetben ennek a bitnek a neve elıjegybit. Érdemes még megnézni most is egy ábrázolható számnak, majd a legnagyobb és legkisebb számnak, valamint a nullának a kódját. 52 komplemens kódja önmaga, így megegyezik az elıjeles-abszolút értékes kódjával, tehát ennek a számnak a komplemens kódja 00110100 2 = 3416 . A − 52 komplemes kódjához meg kell határozni 52-nek 256-ra vonatkozó komplemensét (és általában a − N n-bites komplemens kódjához, ahol 1 ≤ N ≤ 2 n −1 , az N-nek a 2 n -re vonatkozó komplemensét). A legfeljebb n-bites szám nbites komplemensét úgy kapjuk meg, hogy felírjuk a számot n bittel (az egyébként felesleges bal szélsı nullákat sem elhagyva), majd minden bitet kicserélünk úgy, hogy 0 helyére 1-et, 1 helyére 0-t írunk, és ehhez a számhoz hozzáadunk 1-et. Nézzük –52 8-bites komplemens kódját. 5210 = 00110100 2 , majd felcserélve az 1-et a 0-val az 11001011 2 bináris számot kapjuk, és ehhez a számhoz 1-et adva az eredmény 11001100 2 = CC16 , tehát ez lesz a − 52 nyolcbites komplemens kódja. A nyolc bittel ábrázolható legkisebb szám − 128 . 12810 = 10000000 2 , most a bitek felcserélése után a 01111111 2 számot, és ebbıl az 1 hozzáadása után az 10000000 2 = 8016 -at kapjuk, így − 128 komplemens kódja önmaga, tehát 10000000 2 = 8016 . A 0 kódja 00000000 2 = 0016 , és a legnagyobb ábrázolható szám, 127 komplemens kódja 01111111 2 = 7 F16 . Nézzük még meg a − 1 nyolc bites komplemens kódját. Ez a kód az 1 nyolc bites komplemense. 110 = 00000001 2 , ebbıl a bitek átváltása után 11111110 2 -t kapjuk, és 1-et hozzáadva 11111111 2 = FF16 lesz a − 1 nyolc bites komplemens kódja. A komplemens kód sem rendezéstartó, ugyanis most is igaz, hogy negatív szám kódja nagyobb, mint egy nem negatív szám kódja, viszont külön a nem negatív, és külön a negatív számok kódja már rendezéstartó (szemben az elıjeles abszolút értékes kóddal, ahol csak a pozitív számok kódja volt rendezéstartó, a negatív számok esetén a rendezés megfordul). Most általánosságan vizsgáljuk az elıjeles számok ábrázolását.
−
+ ↑ 0
↑ K
− ↑ M
↑ 0
↑ K
a.
↑ 0
↑ K
− ↑ 0
↑ M
↑ 0
↑ K
− ↑ 0
↑ M
↑ M
g.
− ↑ K
+ ↑ K
c.
↑ 0
↑ M
f.
−
+
+ ↑ K
b.
+
↑ M
e.
−
+
+
− ↑ 0
↑ M
d.
+ ↑ K h.
17. ábra
↑ M
38
SZÁMÁBRÁZOLÁS
Az esetek nagy részében az ábrázolandó adatok elıjelesek, így szükségünk van elıjeles számok ábrázolására. Ezt megtehetjük két lépésben is: elıször a szám abszolút értékét kódoljuk mint elıjel nélküli számot, és utána az így kapott kódot tekintve a megfelelı elıjellel, ezt kódoljuk tovább, ezért a továbbiakban már feltehetjük, hogy egész számokat kell kódolnunk. Természetesen a kódtartomány most is ugyanakkora, mint korábban, így a negatív számokat csupán a nem negatívok rovására tudjuk ábrázolni. Általában semmi nem indokolja, hogy az ábrázolt negatív és nem negatív számok száma eltérı legyen, ezért szokásosan ez a két szám megegyezik, vagy legalábbis igen kis mértékben tér el egymástól. Ez azt jelenti, hogy ha a kód az N M halmaz, vagyis az M-nél kisebb nem negatív M egészek halmaza, és K ≈ , akkor a K-nál kisebb számokkal kódoljuk az egyik elıjelhez tartozó 2 számokat, és a többivel a másik csoportot. Az is logikus, hogy külön a negatív számok és a nem negatív számok kódja összefüggı halmazt alkosson. Végül az elıjel nélküli számokhoz hasonlóan most is célszerő, hogy szomszédos számok kódja szomszédos legyen, már amennyire ez lehetséges. Ezeket a szempontokat figyelembe véve nyolc különbözı kód képezhetı: választhatunk, hogy a negatív számok kódja követi-e vagy megelızi a nem negatív számok kódját, másrészt külön-külön dönthetünk, hogy a két részben a kódok sorrendje megegyezik-e az eredeti számok sorrendjével, vagy fordított sorrendben állnak. A nyolc lehetıséget a 17. ábra mutatja. Az alábbiak szerint azonban csak három eset érdekes: a. ha a nem negatív számok kódja van alul, akkor semmi nem indokolja, hogy a természetes kódolástól eltérı ábrázolást alkalmazzunk, ahol a természetes kódolás azt jelenti, hogy minden szám kódja önmaga. Ez viszont azt jelenti, hogy ha a nem negatív számokat kódoljuk a kisebb számokkal, akkor az alsó részen a kódok sorrendje megegyezik az eredeti sorrenddel, így kiesik a c. és d. változat; b. nem jelent lényegesen új kódot, ha egy meglévı kódból úgy kapjuk, hogy a kódszavakat fordított sorrendben rendeljük a kódolandó számokhoz, ezért kimarad az f. és h. ábrán megadott kódolás; c. végül g. a kihagyott c.-nek a tükörképe, így ez sem érdekes variáns. A megmaradt három változat mindegyike fontos a számítógépeknél. Nézzük ezeket részletesen, de elıtte a kódtartományt kissé módosítjuk. Az eddigiekben M értéke r n volt, ahol r a kódoláshoz használt szimbólumok száma, és n a kódszavak hossza, míg a továbbiakban legyen M = ur n −1 , ahol u az r-nél nem nagyobb páros pozitív egész, és legyen K az M-nél kisebb pozitív egész. 1. Az e.-nek megfelelı kódolást részletesebben a 18. ábra mutatja. Az ábráról könnyen leolvasható, hogy a kódolható számok a − K ≤ N < M − K feltételt kielégítı egész számok, és ha N eleme a kódolási tartománynak, akkor ϕ en ( N ) = N + K . Itt az indexben lévı en a kódolás elnevezésére utal, ugyanis ezt a kódolást eltolt nullpontú kódolásnak nevezik. Az elnevezés érthetı: a nullát, és vele együtt minden számot K értékével eltoljuk a számegyenesen.
Számítógépi matematika
39
A kódolás tartománya −K
−1
M −1− K
0
A kódtartomány
K −1
0
K
M −1
18. ábra
Rögtön látjuk, hogy a kódolás rendkívül egyszerő, és hasonlóan egyszerő a dekódolás is, hi−1 szen N ′ = ϕ en ( N ) = N + K -ból N = N ′ − K = ϕ en ( N ′) , ahol N ′ az M-nél kisebb nem negatív egész 1 1 szám. Amennyiben K = ur n −1 = M , akkor a kódolt számoknak pontosan a fele negatív, a kódolás 2 2 1 n −1 1 1 1 tartománya − ur = − M ≤ N < M = ur n −1 és a kódról könnyő eldönteni, hogy negatív szám2 2 2 2 1 nak-e a kódja, ugyanis a kódolható N-re N akkor és csak akkor negatív, ha ϕ en ( N ) < K = ur n −1 , 2 u vagyis pontosan akkor, ha a kódban a legmagasabb helyiértékő jegy kisebb, mint . Ha r = 2 , vagyis 2 n −1 a kód bináris, akkor ez azt jelenti, hogy ha K = 2 , akkor a kódolás tartománya − 2 n −1 ≤ N < 2 n −1 , és a negatív számok kódja 0-val, míg a nem negatívoké 1-gyel kezdıdik. Ennek a kódnak a késıbbiekben kihasználásra kerülı tulajdonsága, hogy rendezéstartó, vagyis ha N 1 és N 2 kódolható számok, úgy N 1 < N 2 és ϕ en ( N 1 ) < ϕ en ( N 2 ) egyszerre igaz. A gyakorlatban K értéke vagy a fentebb már említett 2 n −1 , vagy 2 n −1 − 1 . Ez utóbbi esetben a legmagasabb helyiértékő bit a nem pozitív és a pozitív számokat választja el egymástól. 2. A b.-nek megfelelı kódolást mutatja a 19. ábra. Látjuk, hogy a nem negatív számok kódja önmaga, míg a negatív számok kódját úgy kapjuk, hogy a kódolható negatív számok tartományát ráforgatjuk a nem negatív számok kódja fölötti részre. A kódolás tartománya a − (M − K ) < N < K fel1 1 1 1 1 tételnek megfelelı egészek halmaza, és ha K = M , akkor − ur n −1 = − M < N < M = ur n −1 , 2 2 2 2 2 n −1 n −1 bináris esetben pedig − 2 < N < 2 .
SZÁMÁBRÁZOLÁS
40
A kódolás tartománya − (M − 1 − K )
−1
0
K −1
0
K −1
K +1
M −1
K
A kódtartomány
19. ábra ha 0≤ N
A K-val kódolt nulla neve negatív nulla, és ennek a kódja a bináris elıjeles abszolút értékes kód esetén 2 n −1 , vagyis olyan szám, amelynek a bal szélsı jegye 1, az összes többi jegye 0. A direkt kódolásnál ezt általában nem használjuk, ám mőveletvégzés eredményeként létrejöhet ez a kód. Az elıjeles abszolút értékes kódolás nem rendezéstartó: bármely negatív szám kódja nagyobb valamennyi nem negatív szám kódjánál, és két negatív szám közül a kisebbnek nagyobb az abszolút értéke, így ennek nagyobb a kódja. 3. Az elıjeles számok kódolásának harmadik esete látható a 20. ábrán. Ezt a kódot komplemens kódnak nevezik, így elıször egy szám komplemensével kell megismerkednünk.
Számítógépi matematika
41
A kódolás tartománya − (M − K )
−1
0
K −1
0
K −1
M −1
K
A kódtartomány
20. ábra 0
v u mod v
0
v
2v
u u v v
u mod v
u+v u + 1 v v
21. ábra
u Korábban bevezettük az (u mod v ) = u − v jelölést, ahol u valós szám és v nem nulla vav 1 u u 1 u lós szám. A definícióból kiolvasható, hogy 0 ≤ (u mod v ) = − < 1 , vagyis (u mod v ) az v v v v v törtrésze, és ha v > 0 , akkor 0 ≤ (u mod v ) < v . Ebbıl az is látszik, hogy ha v pozitív egész szám, és u is egész szám, akkor (u mod v ) ≡ u (mod v ) . Általában (u mod v ) jelentése a 21. ábrán látható.
(u
mod v ) fontosabb tulajdonságai a következık:
u < 1 , akkor (u mod v ) = u (pozitív v esetén ez ekvivalens a 0 ≤ u < v , míg negatív v modulusnál a v < u ≤ 0 feltétellel) 1. ha 0 ≤
(u
u mod v ) = u − v , és 1-nél kisebb nem negatív szám egész része 0; v
SZÁMÁBRÁZOLÁS
42
2. ha q ∈ Z , akkor (u + qv mod v ) = (u mod v )
(u + qv
u + qv u mod v ) = u + qv − v = u + qv − v + q = v v
u u = u + qv − v + q = u − v = (u mod v ) v v 3.
((a
;
mod v ) + (b mod v ) mod v ) = (a + b mod v )
a b a − v + b − v v v ((a mod v ) + (b mod v ) mod v ) = a − v a + b − v b − v = v v v , a b a + b a b a + b = a + b − v − v − v − − = (a + b ) − v = (a + b mod v ) v v v v v v 4. ha c ∈ Z , akkor (c(u mod v ) mod v ) = (cu mod v ) u cu − v v ( c ( u mod v ) mod v ) = c u − v uv − v v = ; cu u u cu = cu − cv − v − c = cu − v = ( cu mod v ) v v v v 5. ha a, b és v egyaránt egész szám, akkor
((a
mod v )(b mod v ) mod v ) = (ab mod v )
ha a, b és v mindegyike egész szám, akkor mind (a mod v ) , mind (b mod v ) egész szám, és így 4.-et kétszer alkalmazva kapjuk a bizonyítást; 6.
(a
a mod bc ) = c mod b c mivel bc ≠ 0 , így c sem 0, és a c a a a (a mod bc ) = a − bc = c − b = c mod b . bc c b c
3. azt jelenti, hogy a mod-mővelet lényegében véve összegtartó, míg 5. szerint a szorzattartás is teljesül, ha a modulus és az operandusok egész számok. A 2. tulajdonság mutatja, hogy a számegyenes bármely v hosszúságú, balról zárt és jobbról nyitott intervalluma a [0..v ) illetve a (v..0] intervallumra képzıdik, v elıjelétıl függıen, amint pozitív v esetén a 21. ábra mutatja
Számítógépi matematika
43
Az u valós számnak a nem nulla v valós számra vonatkozó komplemense u (v ) = (− u mod v ) . Bináris esetben ez egyszerően azt jelenti, hogy minden jegy helyére az ellentettjét írjuk, vagyis 0 helyére 1-et, 1 helyére 0-t, és ehhez a számhoz adunk 1-et. ami azt jelenti, hogy a szám végén álló 0-k nem változnak, a jobbról elsı nem nullát az r-re vonatkozó teljes komplemensével helyettesítjük, és az összes többi jegy helyére az r − 1 -re, illetve a legmagasabb helyiértékő pozíción az u − 1 -re vonatkozó teljes komplemensét írjuk. Nézzünk példákat. Mindegyik példában mindkét módon kiszámítjuk a komplemenst. a. α = 56470 10 , r = 10 = u , n = 6 . Ekkor M = 1000000 10 és 5647010 5647010
(1000000 ) (1000000 )
= 05647010 = 05647010
(1000000 )
~ ~ ~ ~ ~ ~ = 0 (9 ) 5 (9 ) 6 (9 ) 4 (9 ) 7 (9 ) 0 (9 ) + 1 = 94352910 + 1 = 94353010
(1000000 )
~ ~ ~ ~ ~ = 0 (9 ) 5 (9 ) 6 (9 ) 4 (9 ) 7 (10 )0 = 94353010 .
b. α = A3C 016 , r = 16 = u , n = 6 . Ekkor M = 1000000 16 és
00 A3C 016 00 A3C 016
(100000016 )
~ ~ ~ ~ ~ ~ = 0 (15 ) 0 (15) A (15 ) 3 (15) C (15 ) 0 (15) + 1 = FF 5C 3F16 + 1 = FF 5C 4016
(100000016 )
~ ~ ~ ~ ~ = 0 (15 ) 0 (15 ) A (15) 3 (15) C (16 ) 0 = FF 5C 4016 .
c. α = 21200 3 , r = 3 , u = 2 , n = 6 . Ekkor M = 200000 3 , és 21200 3 21200 3
( 2000003 )
~ ~ ~ ~ ~ ~ = 0 (1) 2 (2 ) 1 (2 ) 2 (2 ) 0 (2 ) 0 ( 2 ) + 1 = 101022 3 + 1 = 101100 3
( 2000003 )
~ ~ ~ ~ = 0 (1) 2 (2 ) 1 (2 ) 2 (3 )00 = 101100 3 .
d. α = 1101000 2 , r = 2 , n = 8 . Ekkor M = 100000000 2 , és 1101000 2 1101000 2
(100000000 2 )
~ ~ ~ ~ ~ ~ ~ ~ = 0 (1) 1 (1) 1 (1) 0 (1) 1 (1) 0 (1) 0 (1) 0 (1) + 1 = 100101112 + 1 = 10011000 2
(100000000 2 )
~ ~ ~ ~ ~ = 0 (1) 1 (1) 1 (1) 0 (1) 1 (2 ) 000 = 10011000 2 .
A komplemens fogalmának tisztázása után már definiálhatjuk egy szám komplemens kódját. ha 0≤ N < K N , A 20. ábra alapján ϕ k ( N ) = , vagy összevontan ϕ k (N ) = sM + N , M + N , ha − (M − K ) ≤ N < 0 ahol s ismét az elıjelet jelöli, azaz 0, ha a szám nem negatív, és 1 az ellenkezı esetben. Kihasználva, hogy ha 0 ≤ a < b , akkor (a mod b ) = a , míg − b < a < 0 esetén (a mod b ) = (a + b mod b ) = a + b , azt kapjuk, hogy ϕ k ( N ) = sM + N = ( N mod M ) . Az elnevezés onnan származik, hogy ha N negatív, (M )
akkor N = − N , vagyis ebben az esetben ϕ k ( N ) = M + N = M − N = (− N mod M ) = N , azaz komplemens kód esetén egy nem negatív szám kódja önmaga, míg egy negatív szám kódja az M u n −1 abszolút értékének M-re vonatkozó komplemense. Amennyiben M = ur n −1 , és K = = r , 2 2 u akkor látható, hogy a nem negatív számok kódjának elsı jegye kisebb, mint , míg a negatív számok 2
SZÁMÁBRÁZOLÁS
44
u . Ez u = 2 esetén azt jelenti, hogy a nem negatív számok elsı jegye 0, a 2 negatívoké pedig 1, vagyis ekkor ez a bit megegyezik s-sel. Bináris esetben ezt a legmagasabb helyiértékő jegyet elıjegybit-nek szokás nevezni, ugyanis majd látjuk, hogy mőveletvégzéskor ez a bit ugyanúgy részt vesz a mővelet végrehajtásában, mint a kód többi bitje. esetén ez a jegy legalább
Legyen K = 2 n −1 , és ϕ k ( N ) = a n −1 K a 0 = ∑i =0 ai 2 i = a n −1 2 n −1 + ∑i =0 ai 2 i = a n −1 2 n −1 + N 1 a n −1
n−2
− 2 n −1 ≤ N < 2 n −1 szám n-bites bináris komplemens kódja. Ekkor s 2 n + N = ϕ k ( N ) = a n −1 2 n −1 + N 1 -
bıl N = − a n −1 2 n −1 + N 1 , ahol felhasználtuk, hogy a n −1 = s . Érdekes és fontos kapcsolat van egy szám eltolt nullpontú és komplemes kódja között abban a speciális esetben, amikor M = ur n −1 = 2 K . Ekkor
0 ≤ ϕ k (N ) < M , így
ϕ k (N ) = sM + N = sM − K + K + N = . = sM − K + ϕ en (N ) ϕ k ( N ) = (ϕ k (N ) mod M ) = (sM − K + ϕ en ( N ) mod M ) = 1 , = (K + ϕ en ( N ) mod M ) = ur n −1 + ϕ en ( N ) mod M 2
u -t, 2 megkapjuk N komplemens kódját. Ez könnyen látható módon visszafelé is igaz, vagyis ha M = 2 K , akkor úgy tudunk áttérni a komlemens kódról az eltolt nullpontú kódra, vagy vissza, hogy a kód u legmagasabb helyiértékő jegyéhez hozzáadjuk -t, és elhagyjuk az esetleges átvitelt. Ez abban a 2 speciális esetben, amikor u = 2 , azt jelenti, hogy a kód legmagasabb helyiértékő jegye 0 vagy 1, és az áttérés a két kód között pusztán annyi, hogy a legfelsı helyiértéken lévı bitet az ellentettjére cseréljük, azaz 1 lesz, ha eredetileg 0 volt, és viszont. Bináris kód esetén u értéke biztosan 2, tehát ekkor a kódváltás a legmagasabb helyiértékő bit váltását jelenti. Például egy bináris kódban, ahol K az M értékének fele, legyen a szám − 37 . Amennyiben a számokat 8 bittel ábrázoljuk, akkor a két kód rendre ϕ en (− 37 ) = 128 + (− 37 ) = 91 = 01011011 2 és ϕ k (− 37 ) = 1 ⋅ 256 + (− 37 ) = 219 = 11011011 2 , és látható, hogy a két kód pontosan a bal szélsı bitben különbözik. vagyis N eltolt nullpontú kódjában a legmagasabb helyiértékő jegyhez modulo u hozzáadva
Negatív szám komplemes kódja nagyobb, mint egy nem negatív szám komplemens kódja, így a komplemens kód nem rendezéstartó. Ugyanakkor külön a nem negatív, és külön a negatív számok halmazán a komplemens kód már rendezéstartó. Amennyiben a kód bináris és n bites, és K = 2 n −1 , akkor az ábrázolható számtartomány − 2 n −1 ≤ N < 2 n −1 . Ez nem szimmetrikus, aminek az az oka, hogy az egyik oldalon a negatív számokat, a másikon a nem negatívokat, tehát a pozitív számokon kívül a 0-t is kódoljuk. Természetesen a BCD-kódban ábrázolt számok is lehetnek elıjelesek. A BCD-számok elıjelének ábrázolására két módszer terjedt el. Az egyiket fıleg az IBM-gépeknél alkalmazzák. Itt azt használják ki, hogy egy BCD-szám négy biten ábrázolja a 10 különbözı decimális számjegyet, és így a lehetséges 16 négybites kód közül hat kihasználatlan. Ezeket a tetrádokat, nevezetesen az A-tól F-ig terjedı hexadecimális jegyeket használjuk az elıjel ábrázolására. Egy BCD-számjegy egy tetrádot foglal el, vagyis egy bájtban két BCD-jegy helyezhetı el. A jobb oldali félbájton találjuk az alacsonyabb helyiértékő jegyet, a bal oldali félbájton az eggyel magasabb helyiértékő jegyet, ám a szám legalacsonyabb helyiértékő jegye nem egy bájt jobb oldalán, hanem a bal oldali félbájton helyezkedik
Számítógépi matematika
45
el, és ennek a bájtnak a jobb felén jelezzük a szám elıjelét. A hat lehetséges hexadecimális jegy közül az A, C, E és F a pozitív, míg a B és D a negatív elıjelet ábrázolja. Ezek szerint 75341C a 75341 BCD-kódja, míg 75341D a −75341 BCD-kódja ebben a rendszerben. A másik formánál, amelyet egy szabvány rögzít, és amelyet szinte kizárólagosan használnak a kisgépeknél (és a mikroprocesszorok hardverjében), a BCD-számokat szintén egy-egy félbájton adjuk meg, a jobb oldali félbájton az alacsonyabb helyiértékkel, ám itt a szám legalacsonyabb helyiértékő jegye a megfelelı bájt jobb felén áll, és az elıjelet a legmagasabb helyiértékő bájt elıtt, egy teljes bájton ábrázoljuk. A szabvány szerint a pozitív elıjel a 0016, míg a negatív elıjel a 8016 bájt. Ebben a rendszerben 00075341 az elıbbi 75341, és 80075341 a −75341 BCD-kódja. A fixpontos számábrázolás nagy problémája, hogy ha egyaránt kell mind igen kicsi, mind igen nagy számokat ábrázolni, akkor nem gazdaságos. A nagy számok ábrázolásához ugyanis sok bitre van szükség, amelyek nagy része a kis számok ábrázolásánál 0 (illetve 1 a negatív számok komplemens és eltolt nullpontú kódolásánál). Az is problémát okoz, hogy a kis számok relatív pontossága kicsi, hiszen a valós adatok ritkán pontosan egész számok, márpedig a kódolásnál egésznek tekintettük ıket, így a törtrészük elvész. A problémát a lebegıpontos számábrázolás oldja meg. Ennél a kódolásnál csaknem valamennyi számot ugyanannyi értékes jeggyel ábrázolunk, így a relatív pontosságuk megegyezik. Ezt úgy érjük el, hogy az α számot α = md k alakban adjuk meg, ahol a d bázis értéke, géptıl függgıen, általában 2 vagy 16 (a kisgépekben általában az elıbbi a szokásos, sıt, szinte kizárólagos). Az m mantissza értékét n-bites fixpontos számként ábrázoljuk úgy, hogy ha α ≠ 0 , akkor 1 ≤ m < d
1 ≤ m < 1 , és ismét a géptıl függ, hogy a két eset közül melyik érvényes az adott gépben. Ha d egy számot így adunk meg, akkor azt mondjuk, hogy a szám normalizált. Erre tehát az jellemzı, hogy a szám abszolút értékének kódjában d = 2 esetén a legmagasabb helyiértékő bit, míg ha d = 16 , akkor a legmagasabb helyiértékő négy bit legalább egyike nem 0. A lebegıpontos számábrázolásnál a szám kódja a mantissza fixpontos kódjából és a kitevı fixpontos kódjából álló számpár. Ha d = 2 , és a szám kódja normalizált, akkor az elıbbiek szerint a mantissza abszolút értékének legmagasabb helyiértékő bitje biztosan 1, így azt felesleges megadni. Legyen például a kód felépítése olyan, hogy d = 2 , a mantisszát elıjeles abszolút értékes kóddal adjuk meg, ahol a mantissza abszolút értéke 1 és 2 közé esik, de a legmagasabb helyiértékő, 1 értékő bitet nem ábrázoljuk, és így a mantissza csonkolt abszolút értékő kódját 10 bittel adjuk meg, a kitevıt eltolt nullponttal, 5 biten adjuk meg, az eltolás értéke 2 5−1 − 1 = 15 , és a kódban a bal szélsı bit a szám elıjele, majd következik a kitevı kódja, és végül a mantissza módosított 10 bites kódja. Határozzuk meg − 82 ilyen felépítéső lebegıpontos kódját. 8210 = 1010010 2 = 1,010010 2 × 2 6 , és így a szám kódja 1 10101 0100100000 . Ebben a kódban a bal szélsı 1 mutatja, hogy a szám negatív, a következı öt bit, 10101 , a kitevı kódja, amelyet úgy kaptunk, hogy a 6 kitevıhöz hozzáadtuk az eltolás értékét, 15-öt, és így kaptuk a 21-et, amelynek bináris kódja éppen az elıbbi 10101 . Végül az utolsó tíz bit, 0100100000 a korábban megadott mantissza, 1,010010 2 kódja, amelyet úgy kapunk, hogy elhagyjuk az egész részt képviselı 1-et, és a számot jobbról kiegészítjük a tíz bithez szükséges hat értéktelen 0-val. Négy speciális eset van. Amennyiben a kód s 00000 mmmmmmmmmm , ahol s akár 0, akár 1, és az m-ek legalább egyike 1 (az azonosan jelölt mek különbözı értéket képviselhetnek, tehát bármelyikük lehet 0 vagy 1), akkor a szám nem normalizált, és nincs elhagyott 1-es, vagyis ez a kód a (− 1)s 0, mmmmmmmmmm × 2 −14 számnak fele meg. Az s 00000 0000000000 kód a 0 kódja, ez az úgynevezett gépi nulla. s 11111 0000000000 a pozitív illetve negatív végtelen kódja, végül ha legalább egy m nem nulla, akkor s 11111 mmmmmmmmm vagy
egy nem szám kódja. Könnyen látható, hogy a legkisebb abszolút értékő normalizált szám 1 × 2 −14 az 0 00001 0000000001 kóddal, és a legnagyobb abszolút értékő normalizált szám 2 − 2 −10 × 215 , amelyhez a 0 11110 1111111111 kód tartozik. A legkisebb abszolút értékő (nem normalizált), nullától
(
)
különbözı szám 2 −10 × 2 −14 = 2 −24 a 0 00000 0000000001 kóddal, és a legnagyobb abszolút értékő,
(
)
nem normalizált szám 1 − 2 −10 × 2 −14 , amelynek a kódja 0 00000 1111111111 (valamennyi kódnál feltettük, hogy a szám pozitív, negatív szám esetén csak annyi az eltérés, hogy a bal szélsı bit 1).
SZÁMÁBRÁZOLÁS
46
A fixpontos számábrázolásnak két problémáját említhetjük. Az egyikrıl már volt szó, nevezetesen arról, hogy amennyiben az ábrázolható számtartományhoz képest kis értékő számot adunk meg, akkor nagy a kódolás relatív hibája. A másik is a mérethez kapcsolódik: ha a géppel igen sok különbözı típusú problémát akarunk megoldani, akkor a kód hosszának olyannak kell lennie, hogy igen nagy számok is elférjenek benne, ugyanakkor a kis számok kódja a magasabb helyiértékeken csak nullát tartalmaz, vagyis a kód jegyeinek túlnyomó többsége kihasználatlan. Ezen a két problémán segít az úgynevezett lebegıpontos számábrázolás. Legyen d egy rögzített, 1-nél nagyobb egész szám, a bázis, és α ∈ R . Ekkor α felírható α = md k alakban, és α megadható (m, k ) rendezett párként. Itt m a szám mantisszája, és k a kitevı, vagy karakterisztika. Ha most m-et és k-t fixpontos alakban ábrázoljuk, akkor α kódja egy fixpontos rendezett pár lesz. Az nyilván igaz, hogy ha m tetszıleges valós szám, és k egy bármilyen egész szám, akkor van egy és csak egy olyan α valós szám, amelynek a mantisszája m és a karakterisztikája k az adott és rögzített d esetén, nevezetesen α = md k . Ez azt jelenti, hogy adott d esetén az (m, k )∈ R × Z pár egyértelmően meghatározza az R egy és csak egy elemét. Visszafelé azonban ez egyáltalán nem igaz, ugyanis tetszıleges l egész szám esetén md k = md l d k −l = m ′d k ′ , vagyis egy α valós számhoz végtelen sok (m, k )∈ R × Z rendezett pár rendelhetı. Az egyértelmőséget a következı módon tudjuk biztosítani. Rögzítsünk egy t egész számot. Ha α = 0 , akkor m = 0 , és legyen ekkor k = 0 , egyébként legyen d t −1 ≤ m < d t . Ekkor d t −1 ≤ m = α d − k < d t -bıl − t + log d α < k ≤ −t + log d α + 1 , vagyis
(
)
k = log d α − t + 1 , és ha már ismerjük k-t, akkor m = αd − k . Az így meghatározott m és k már egyér-
telmő, és ezzel az (m, k ) párral felírva kapjuk az α (a megadott paraméterekhez tartozó) normalizált lebegıpontos alakját, míg más mantissza-kitevıpár ugyanezen szám nem normalizált alakja. A lebegıpontos számok mantisszáját általában elıjeles abszolút értékes formában ábrázolják, és ha M = ur n −1 -ben u = 2 , akkor a kód legmagasabb helyiértékő jegye az elıjel, és a szám abszolút értéke megegyezik a kód többi jegye által meghatározott számmal. Most tekintsük csak ezt a részét a kódnak. Tegyük fel, hogy a mantissza abszolút értékét az r-alapú számrendszerben n jeggyel ábrázoljuk, és az r-edespont a kódban az r l -hez tartozó jegy jobb szélén van (l tetszıleges egész szám lehet), n −1
vagyis, ha a mantissza abszolút értékének kódja a n −1 K a 0 , akkor m = r −l ∑i =0 ai r i . A korábbiak alapján az a célszerő, ha a kitevıt úgy választjuk meg, hogy a normalizált alakban megadott szám mantisszája abszolút értékének kódjában a lehetı legkevesebb vezetı nulla legyen. Ez úgy érhetı el, ha r n −1−l < d t ≤ r n −l , vagyis ha l = n − t log r d . Amennyiben d = r v egy pozitív egész v-vel, akkor
( )
t
l = n − tv . Ekkor r n−l = r tv = r v = d t , és ebben az esetben r n −l − v = d t −1 ≤ m < d t = r n −l , vagyis most a mantissza abszolút értékének kódjában a bal szélsı v jegy legalább egyike nem 0. A leggyakoribb három eset r = 2 , d = 2 , t = 0 , majd r = 2 , d = 2 , t = 1 , végül r = 2 , d = 16 1 , t = 0 . Az elsı esetben a szám mantisszája valódi bináris tört, 0,12 = ≤ m < 1 = 1,0 2 , a kettedespont 2 a mantissza abszolút értéke kódjának bal szélén van, és a kód legmagasabb helyiértékő jegye nem 0, vagyis 1. A második esetben 1,0 2 = 1 ≤ m < 2 = 10 2 , és az elızıhöz képest annyi az eltérés a kódban, hogy most a kettedespont a kód bal szélsı jegyének jobb oldalán helyezkedik el. Végül a harmadik 1 esetben 0,00012 = 0,116 = ≤ m < 1 = 1,016 = 1,0 2 , a mantissza abszolút értékének kódjában a 16 kettedespont a kód bal szélén áll, és a kód bal szélsı tetrádja nem nulla, vagyis a kód bal szélsı négy bitjébıl legalább az egyik 1. A lebegıpontos számábrázolásban, mint látjuk, a számot egy fixpontos számpárral reprezentáljuk. Egy gyakori megoldást mutat a 22. ábra, ahol a jobb szélsı l biten van a mantissza abszolút értékének kódja, az utána következı n − l − 1 biten a karakterisztika kódja, végül a bal szélsı bit a szám elıjelbitje. Abban az esetben azonban, ha d = 2 , akkor láttuk, hogy normalizált alakban a man-
Számítógépi matematika
47
tissza abszolút értékének kódjában a legmagasabb helyiértékő bit biztosan 1, és ez nem jelent információt. Ekkor a legtöbb esetben ez a bit elhagyható, felesleges tárolni, aminek az a következménye, hogy ugyanolyan hosszon kétszer akkora pontossággal ábrázolhatóak a számok. Amikor a gép egy ilyen módon tárolt számmal számol, akkor automatikusan elhelyezi a mantissza bal szélén a korábban elhagyott 1-est, elvégzi a mőveletet, és ha a mővelet eredménye egy normalizált lebegıpontos szám, és a végeredményt tároló változó deklarációja olyan, akkor tárolás elıtt ismét elhagyja a tárolás szempontjából felesleges bitet.
n-1
n-2
0
l-1
l 22. ábra
Még azt nézzük meg, hogy mekkora az ábrázolás hibája lebegıpontos számábrázolás esetén. Csak azt az esetet vizsgáljuk, amikor d = r v egy pozitív egész v-vel, és tegyük fel, hogy a mantissza abszolút értékének kódjában az r-edespont az l-edik helyiérték jobb oldalán van. Legyen α = md k > 0 (a lebegıpontos számok ábrázolásához használt fixpontos alak következtében elegendı a pozitív számokat vizsgálni). Ha a szám normalizált, akkor d t −1 ≤ m < d t (feltéve, hogy a szám nem nulla), és két szomszédos kódhoz tartozó szám eltérése r − l d k , vagyis az abszolút hiba értéke k-tól exponenciár −l d k r − l d k r −l d k ≤ , vagyis r − l −vt < h ≤ r −l − v (t −1) = r v (r − l − vt ) , így a relatív lisan függ. Ugyanakkor t k < k t −1 k d d md d d hiba egy szők tartományban változik, és a legkisebb és legnagyobb relatív hiba aránya r v .
49
DIGITÁLIS ARITMETIKA A következıkben azt vizsgáljuk meg, hogy hogyan végzi a számítógép a mőveleteket a különbözı kódok esetén. Mielıtt a konkrét eseteket néznénk, egy általános problémát kell megbeszélnünk. Tegyük fel, hogy adott egy n-változós Op mővelet, amely tehát n számhoz egy egyértelmően meghatározott számot rendel. A gépben nem ez az n szám, hanem a számok kódja áll, így a gép a számok kódjaival operál. A gépnek egy olyan Op ′ mőveletet kell megvalósítania, amellyel teljesül, hogy bármely c1 , K , c n operandus esetén ϕ (Op (c1 , K , c n )) = Op ′(ϕ1 (c1 ), K , ϕ n (c n )) , ahol ϕ (c ) a c kódja, és nem zártuk ki azt a lehetıséget, hogy valamennyi operandust más és más kóddal adunk meg, és az eredmény kódja is különbözhet az operandusok kódjaitól. Mint tudjuk, az r-alapú számrendszerben n jeggyel r n különbözı számot tudunk kódolni, így minden más szám csak valamely közelítı értékével kódolható. A továbbiakban mindig feltesszük, hogy az operandusok pontosan kódolható értékek, azaz olyan számok, amelyeknek a kódját dekódolva, az eredeti számot kapjuk vissza. Ebbıl azonban nem következik, hogy ez az eredményre is igaz legyen. Mind a jobb oldalon, azaz a legalacsonyabb helyiértékő jegyeknél, mind a másik oldalon, egymástól függetlenül, lehetséges, hogy jegyek vesznek el, mert az eredményben kevesebb hely áll rendelkezésre a szükségesnél, és az is lehetséges, hogy az eredmény akár az egyik, akár a másik oldalon az operandusok és a mővelet által megköveteltnél több jegyet képes ábrázolni. Az utóbbi eset nem vezet hibához, csupán gazdaságtalan, viszont a szükségesnél kevesebb jegy torzítja az eredményt. Mint láttuk, ez a torzítás mindkét szélen elıfordulhat, azonban a jelentısége lényegesen eltérı. Ha az eredményt n jeggyel ábrázoljuk, és a szám jobb szélsı jegyének súlya r − m (m negatív, illetve 0 is lehet), akkor jobb oldali levágásnál az abszolút hiba kisebb, mint r − m , és a relatív hiba kisebb, mint r −m , ha az eredmény a nullánál nagyobb α, míg a másik oldalon az abszolút hiba legalább r n − m ab-
α
r n− m
relatív értékben. A két érték aránya mind az abszolút hibát, mind a α relatív hibát tekintve, r n , vagyis a bal oldali jegyvesztés lényegesen súlyosabb, mint a jobb oldali levágás. Nyilvánvaló, hogy az elıbbi eset teljesen hamis eredményhez vezet, míg a másik esetben az eredmény hibája azonos magának a kódolásnak a hibájával. Az eddigiek egy lehetséges esetét mutatja a 23. ábra. Itt a bal oldalon értékes jegyek vesznek el, míg a jobb oldalon helykitöltı nullákkal kell a felesleges helyet kitölteni, vagyis a bal oldalon jelentıs, az eredményt teljesen eltorzító hiba lép fel, míg a jobb oldalon szükséges kiegészítés gazdaságtalan. szolút értékben, és minimum
1. operandus kódja 2. operandus kódja
az eredmény helyigénye az eredmény kódja
23. ábra
A mőveleteket két csoportba soroljuk: 1. additív mőveletek a) összeadás b) kivonás
DIGITÁLIS ARITMETIKA
50 2. multiplikatív mőveletek a) szorzás b) osztás
Mindkét típusnál megnézzük az egyes adatábrázolási módok specialitásait. A kérdés mindig az, hogy hogyan végezzük a mőveletet a kódokkal, hogy a helyes eredmény kódját kapjuk. Azt persze egyik esetben sem várhatjuk, hogy ha a papíron számított eredmény nem fér el az ábrázolható tartományban, akkor a gép a helyes eredményt szolgáltassa. Elıször a bináris összeadást és kivonást tekintjük át, majd áttérünk az általános esetre. Az elıjel nélküli számok összeadását a gép ugyanúgy végezheti, mint ahogy mi magunk is számolunk: összeadjuk jobbról balra az azonos pozíción álló jegyeket, és ezt módosítjuk az elızı pozíción keletkezı átvitellel. Az átvitel értéke csak 0 és 1 lehet, hiszen két bit összege maximum 2, és ha az elızı helyiértékrıl az átvitel értéke 1 volt, akkor még mindig csak 3-at kapunk, amelybıl 1 lesz az összeg megfelelı bitje, és ismét csak 1 lesz az átvitel. Tegyük fel, hogy a két operandust és az eredményt azonos hosszon adjuk meg. A probléma akkor jelentkezik, ha a bal szélsı jegyek összeadásakor is 1 lesz az átvitel, hiszen ez az 1 már nem fér be a megadott regiszterbe. Ilyenkor úgynevezett átvitel, angolul carry keletkezik, amelyet a gép egy állapotregiszter, másként státuszregiszter egy bitjében, az átviteljelzıben, a carry flagben tárol. Láttuk, hogy az átvitel legfeljebb 1 lehet, így egy bittel, az átvitelbittel, a carry bittel megadható. Az állapotregiszter egyes bitjei a gép mőködése során keletkezı különbözı eseményeket rögzítenek, és ezek a bitek az egyes mőveletek elvégzésekor automatikusan állítódnak, de mindig csak azok a bitek, amelyeknek az adott mővelet esetén van értelme. Az állapotregiszter legtöbb bitje programmal lekérdezhetı, módosítható, törölhetı és állítható, valamint bizonyos utasításoknál az utasítás végrehajtása a státuszregiszter egy bitjétıl függhet. Amennyiben olyan nagy számokat kell összeadnunk, amekkora számot a gép közvetlenül, azaz gépi utasítással nem tud kezelni, akkor nekünk kell program segítségével elvégezni az összeadást, és ilyenkor az egyes lépéseknél keletkezı átvitelt a következı összeadásnál hozzá kell adni a keletkezett összeghez. A kivonás hasonló az összeadáshoz, csak most nem az átvitel, hanem az áthozat okozhat problémát, ám ennek a kezelése hasonló az összeadáshoz. Eltolt nullpontú számok összeadása és kivonása könnyő. Ha a két operandus N 1 és N 2 , akkor
(
) (
)
ϕ en ( N1 + N 2 ) = ( N1 + N 2 ) + 2 n −1 = N 1 + 2 n −1 + N 2 + 2 n −1 − 2 n −1 = ϕ en ( N 1 ) + ϕ en ( N 2 ) − 2 n −1 , feltéve, hogy az eltolás értéke 2 n −1 , és hogy − 2 n −1 ≤ N 1 + N 2 < 2 n −1 (ha az eltolás értéke 2 n −1 − 1 , akkor az értelemszerő módosításon túl csak a megadott határokban van változás). Abban az esetben, ha az összeg kilép a megengedett intervallumból, akkor túlcsordulás keletkezik, amit az állapotregiszterben lévı túlcsordulásbit, másként Overflow flag jelez, és amelyet a gép ismét automatikusan beállít. Könnyen látható, hogy túlcsordulás csak akkor keletkezhet, ha a két operandus azonos elıjelő. Az is könnyen belátható, hogy a kivonás csak annyiban különbözik az összeadástól, hogy most az eltolás értékét nem levonni, hanem hozzáadni kell a kódok különbségéhez. Az elıjeles abszolút értékes kódolás esetén, ha közvetlenül végezzük az összeadást, akkor esetszétválasztást kell alkalmazni. Amennyiben a két szám azonos elıjelő, vagyis a két kód bal szélsı bitje azonos, akkor össze kell adni a két szám abszolút értékét, azaz a két kódot úgy, hogy elhagyjuk a bal szélsı elıjelbitet. Az összeg elıjele a két operandus közös elıjele, tehát a bal szélsı bitjük, így ezt kell elhelyezni az összeg bal szélsı bitjének a helyére, és a további bitek az abszolút értékek összegének megfelelı bitek. Amennyiben viszont a két szám különbözı elıjelő, akkor a nagyobb abszolút értékő szám kódjának az abszolút értéket tartalmazó részébıl (tehát a kód bal szélsı bitjének elhagyásával keletkezett számból) ki kell vonni a kisebb abszolút értékő szám kódjának az abszolút értéket tartalmazó részét, ez lesz az eredmény abszolút értéke, és az így kapott értéket balról ki kell egészíteni a nagyobb abszolút értékő szám kódjának bal szélsı bitjével, mint az eredmény elıjelbitjével (ha a két, különbözı elıjelő szám abszolút értéke azonos, akkor bármelyiket tekinthetjük „nagyobb” abszolút értékőnek). Helyes eredmény természetesen az elıjeles abszolút értékes kód esetén is csak akkor ke-
Számítógépi matematika
51
letkezik, ha nincs túlcsordulás, vagyis ha − 2 n −1 < N 1 + N 2 < 2 n −1 , és túlcsordulás most is csak azonos elıjelő számok összeadásakor keletkezhet. A kivonás ennél a kódolásnál közvetlenül visszavezethetı az összeadásra úgy, hogy a kivonandó kódjának bal szélsı, az elıjelet mutató bitjét az ellentettjére változtatjuk, vagyis a 0-t 1-re, illetve az 1-et 0-ra cseréljük. Nézzük a komplemens kódot. Legyen a két egész szám, amelyet össze akarunk adni, N 1 és N 2 , és − 2 n −1 ≤ N1 < 2 n −1 , − 2 n −1 ≤ N 2 < 2 n −1 , ekkor − 2 n ≤ N = N 1 + N 2 < 2 n . A két szám kódja a
komplemens kódolás szabályának megfelelıen ϕ k ( N 1 ) = s1 2 n + N 1 és ϕ k ( N 2 ) = s 2 2 n + N 2 , és ha a két operandus összege elfér a megengedett számtartományban, azaz − 2 n −1 ≤ N 1 + N 2 < 2 n −1 , akkor az összeg kódja ϕ k ( N ) = ϕ k ( N 1 + N 2 ) = s 2 n + ( N1 + N 2 ) . Az elıbbiekbıl adódik, hogy
(
) (
)
ϕ k ( N 1 ) + ϕ k ( N 2 ) = s1 2 n + N 1 + s 2 2 n + N 2 =
(
)
= (s1 + s 2 − s )2 n + s 2 n + ( N 1 + N 2 ) = (s1 + s 2 − s )2 n + ϕ k ( N )
.
Figyelembe véve, hogy t = s1 + s 2 − s ≥ 0 , és a gép n jegyre számol, ϕ k ( N1 ) + ϕ k (N 2 ) = t 2 n + ϕ k (N ) jobb oldalából a gépben csak ϕ k (N ) marad meg, így a két kód n-bites összege megegyezik az operandusok összegének n-bites kódjával. Ez az eredmény azt mutatja, hogy komplemens kód esetén az öszszeg kódja egyszerően a két kód összege, feltéve, hogy nincs túlcsordulás, vagyis az operandusok öszszege is benne van az ábrázolható tartományban. Ez azt jelenti, hogy az elıjeles fixpontos kódok között a komplemens kód esetén a legegyszerőbb az összeadás, és ezért a számítógépekben szinte kizárólagos a fixpontos számok kódolásánál a komplemens kód (a korábbiakban pedig már mondtuk, hogy a fixpontos számokat a gép általában egész számként kezeli). Kivonáshoz elegendı tudni, hogy mi lesz egy szám ellentettjének a kódja, ha ismerjük az eredeti szám komplemens kódját, hiszen ekkor a kivonást egyszerően vissza tudjuk vezetni az összeadásra. Erre a kérdésre könnyő a válasz:
(
)
ϕ k (− N ) = (1 − s )2 n + (− N ) = 2 n − s 2 n + N = 2 n − ϕ k ( N ) = ϕ k ( N ) n bittel számolva, feltéve, hogy a szám nem nulla. A 0 ellentettje 0, tehát a kódok is azonosak, és a fenti kifejezéssel is ez az eredmény, ha figyelembe vesszük, hogy az eredmény is n biten keletkezik. Most nézzük általában az additív mőveleteket. Elsıként az elıjel nélküli számok összeadását tekintjük. Ekkor az α szám kódja az r-alapú számrendszerben ( r mα mod r n ) , ahol m egész szám és n pozitív egész szám (mint emlékszünk, egy ilyen kódban a számokat n jeggyel adjuk meg, és az r-edespont a szám jobb szélétıl m jegyre helyezkedik el balra, ha m nem negatív, és jobbra, ha az m kisebb nullánál). Ha a kódolandó szám hiba nélkül kódolható, akkor r n > r m α ∈ N , α = ∑i =− m ai r i és ϕ (α ) = ( r mα mod r n ) = r mα . n −1− m
Az összeadás kétváltozós mővelet, azaz két operandusa van, mondjuk α 1 és α 2 . Legyen az elsı operandus kódjában az elıbbi m és az n értéke rendre m1 és n1 , a másodikban m2 és n2 , továbbá az eredmény kódjában egyszerően m és n, végül m ′ = max{m1 , m 2 } , és t = max{n1 − m1 , n 2 − m 2 } .
Ekkor ϕ1 (α 1 ) = r m1 α 1 -bıl r m′α 1 = r m − m1 ϕ1 (α 1 ) ∈ N , és hasonlóan r m′α 2 = r m − m2 ϕ 2 (α 2 ) ∈ N . Összead′
′
va a két értéket ismét egy nem negatív egész számot kapunk, vagyis r m′ (α 1 + α 2 ) ∈ N , és így α 1 + α 2
biztosan felírható olyan alakban, ahol a legalacsonyabb helyiértéken r − m′ áll. Mivel α = r − m′ ábrázolható szám, és 0 + α = α , ezért létezik olyan operanduspár, amelyben szükség van az elıbbi legalacsonyabb helyiértékre, vagyis ha nem akarunk a jobb oldalon jegyeket veszíteni, akkor m ≥ m′ . Nézzük a kód másik szélét. Ha α = r t −1 , akkor ez ábrázolható szám, és 0 + α = α következtében lesz olyan
DIGITÁLIS ARITMETIKA
52
összeg, amelyben az r t −1 -nek megfelelı pozíción nem 0 áll. α 1 ≤ r n1 − m1 − r − m1 ≤ r t − r − m′ , és hason-
(
)
lóan, α 2 ≤ r t − r − m′ , tehát α 1 + α 2 ≤ r t + r t − 2r − m′ < 2r t ≤ r t +1 , így α 1 + α 2 -ben legfeljebb a t-nek megfelelı pozíción áll értékes jegy. Most tegyük fel, hogy például n1 − m1 ≥ n 2 − m 2 > − m1 . Ekkor
(
)
α 1 + α 2 = r n1 − m1 − r n2 − m2 −1 + r n2 −1− m2 = r n1 − m1 = r t , vagyis ilyen esetben szükség van az r t -hez tartozó jegy ábrázolására. Ha viszont − m1 ≥ n 2 − m 2 , akkor a két kóddal ábrázolható maximális számok összege
(
) (
)
α 1 + α 2 = r n1 − m1 − r − m1 + r n2 − m2 − r − m2 < r n1 − m1 − r − m1 + r n2 − m2 ≤ r n1 − m1 − r − m1 + r − m1 = r n1 − m1 = r t , és így még a két maximális számot összeadva is r t -nél kisebb számot kapunk, elegendı bal oldalon az r t −1 -nek megfelelı jegyig ábrázolni a számot. Összefoglalva azt kaptuk, hogy az összeg ábrázolásához legfeljebb t + 1 + m′ jegy kell, amelybıl m′ áll az r-edes ponttól jobbra (illetve − m ′ -vel balra, ha m′ negatív), de ha az egyik kód maximálisan ábrázolható értéke kisebb, mint a másik kóddal ábrázolható minimális szám, akkor a t + m ′ hosszúság is elegendı. Az összeg kódja ϕ (α 1 + α 2 ) = r m r − m1 ϕ1 (α 1 ) + r − m2 ϕ 2 (α 2 ) mod r n , vagyis a gép úgy végzi az összeadást, hogy a két kódnak a kódszóban rögzített helyen található r-edespontját összeilleszti, végrehajtja az összeadást, majd az eredmény mindkét végén, egymástól függetlenül, vagy elhagy jegyeket, vagy kiegészítı nullákat illeszt a számhoz, attól függıen, hogy n − m és t, illetve m és m′ hogyan viszonyul egymáshoz. Ha a szokásoknak megfelelıen a kódok azonosak, vagyis m1 = m = m 2 és n1 = n = n 2 , azaz
( (
(
)
)
)
ϕ1 = ϕ = ϕ 2 , akkor ϕ (α 1 + α 2 ) = ϕ (α 1 ) + ϕ (α 2 ) mod r n . A feltétel szerint r n > ϕ (α 1 )∈ N , és a
másik operandusra hasonlóan r > ϕ (α 2 ) ∈ N , ám az nem feltétlenül igaz, hogy r n > ϕ (α 1 ) + ϕ (α 2 ) (az természetesen teljesül, hogy a két kód összege nem negatív egész szám). A kódok összegérıl csak annyit tudunk, hogy ϕ (α 1 ) + ϕ (α 2 ) < 2r n (még pontosabban ϕ (α 1 ) + ϕ (α 2 ) ≤ 2r n − 2 ), és sajnos lehetn
séges, hogy ϕ (α 1 ) + ϕ (α 2 ) ≥ r n . Ekkor a két kód összege nem fér el a megadott hosszon, és így a gép a bal szélsı legmagasabb helyiértékő jegyet levágja. A korábbi eredmény alapján ez a levágott jegy csak 1 lehet. Nem veszítünk információt, ha a gép ezt a plusz jegyet, amely tehát vagy 0, vagy 1, a mővelet elvégzése után tárolja, és megfelelı utasítással vizsgálni tudjuk ezt a jegyet. Ezt az egy bittel ábrázolható jegyet átvitelnek, vagy carry-nek, a megfelelı bitet átvitelbitnek, carry bitnek nevezzük. A gépben még több ilyen, egy-egy bittel ábrázolható információ keletkezik a mőveletvégzés során, például, hogy az eredmény negatív, vagy az eredmény 0, és még további hasonló jegy. Egy-egy ilyen jegyet flag-nek nevezünk, és egy regiszterben, az úgynevezett állapot- vagy státuszregiszterben tároljuk ıket. Az elıbbiek szerint van átvitelflag vagy carryflag, elıjelflag, zéróflag, és még további flagek, amelyek közül eggyel késıbb megismerkedünk. A státusregiszter bitjei az egyes mőveletek jellegétıl függıen automatikusan állítódnak, és az értékük, mint már említettük, utasítással lekérdezhetı, továbbá szintén utasítással egyes bitek módosíthatóak, illetve állíthatóak vagy törölhetıek. Az is lényeges, hogy bizonyos utasítások végrehajtása automatikusan figyelembe veszi a megfelelı státuszbit értékét, vagyis különbözı tevékenységet végez a bit különbözı értékénél. Kérdés, hogy hibát jelent-e, ha két elıjel nélküli szám összeadásakor az átvitelbit értéke 1, azaz az eredmény nem fér el a megadott mérető helyen. Adott esetben ez valóban jelenthet hibát, ám nem mindig. Gondoljuk meg, hogy a gép csak adott nagyságú számokkal tud operálni. Ha ennél nagyobb számokkal kell dolgoznunk, akkor ezt úgy tehetjük meg, mint ahogy a hétköznapi életben is eljárunk, nevezetesen, a számot több jeggyel ábrázoljuk, csupán most egy-egy jegy valójában egy, az r-alapú számrendszerben felírt n-jegyő szám (vagyis az egészet úgy tekinthetjük, hogy a számot az r n -alapú számrendszerben ábrázoljuk), és a gép egy-egy lépésben egy-egy ilyen számjegyen operál. Ekkor az összeadást, úgy, mint papíron is, a legalacsonyabb helyiértékő jeggyel kezdjük, és jobbról balra haladva végezzük a mőveletet, úgy, hogy közben minden lépésben keletkezhet egy átvitel, ahol az átvitel értéke vagy 0 (vagyis valójában nincs átvitel), vagy 1. Ekkor a helyes eredményhez mindig figyelembe kell vennünk az átvitelt, vagyis a két összeadandó megfelelı helyiértékő jegyének össze-
Számítógépi matematika
53
adásakor ehhez az összeghez hozzá kell adni az elızı pozíción keletkezett átvitelt, és az összeadás során elı kell állítani az aktuális átvitelbitet. Fentebb láttuk, hogy ϕ (α 1 ) + ϕ (α 2 ) ≤ 2r n − 2 , így, ha az elızı jegyek összeadásakor átvitel keletkezett, akkor az aktuális pozíción elvégezve az összeadást, az eredményre teljesül, hogy ϕ (α 1 ) + ϕ (α 2 ) + 1 ≤ 2r n − 1 < 2r n , tehát az átvitel értéke most is csak 0 vagy 1 lehet. Az elıjel nélküli számok kivonása hasonló az összeadáshoz. Ha a kivonandó nagyobb, mint a kisebbítendı, akkor a kivonás csak úgy végezhetı el, ha igénybe veszünk egy áthozatot, és ezt az átvitelbittel tehetjük meg, vagyis ezzel jelezzük, hogy áthozatra lenne szükség. Ha az operandusok egyjegyőek, akkor az áthozat 1 értéke hibát jelez, ám többjegyő számokkal végezve a mőveletet, ez csak akkor jelent hibát, ha az utolsó (azaz a legmagasabb helyiértékő) jegyekkel végzett mővelet után 1 az értéke ennek a bitnek. Most az egyes jegyeken végzett kivonás során az átvitelbitet ki kell vonni a két jegy kivonásakor keletkezett eredménybıl, és ha szükséges, akkor ismét igénybe kell venni az átvitelbitet. Tegyük fel, hogy egy adott pozíción végezve a kivonást, áthozatra van szükség. Ekkor a következı helyiértéken az elvégzendı mővelet ϕ (α 1 ) − ϕ (α 2 ) − 1 . Mivel ϕ (α 1 ) ≥ 0 és ϕ (α 2 ) ≤ r n − 1 , ezért
r n + ϕ (α 1 ) − ϕ (α 2 ) − 1 ≥ 0 , azaz ezen a pozíción is legfeljebb csak 1 lehet a szükséges áthozat. Legyen például a gépben r = 3 és n = 3 , és az elsı operandus értéke 1541, a másodiké 884. 1541-et három jeggyel tudjuk megadni: a legalacsonyabb helyiértékő jegy 1541 mod 3 3 = 2 , a má-
(
)
1541 sodik jegy mod 3 3 = 57 mod 33 = 3 , végül a legmagasabb helyiértékő jegy hasonló szá 27 mítással 2, azaz 154110 = 232 27 . A 884-nek megfelelı három jegy ismét jobbról, tehát a legalacso-
(
)
nyabb helyiértékő jegytıl kezdve 20, 5 és 1, tehát 88410 = 1520 27 . Most vonjuk ki az 1541-nek megfelelı kódsorozatból 884 kódsorozatát. Elıször ki kell vonni a 2-bıl a 20-at. Az eredményhez igénybe kell venni egy áthozatot, amelynek az értéke 33 = 27 , tehát 27 + 2 = 29 -bıl vonjuk ki a 20-at, az eredmény 9, és az átvitelbit értéke 1. Ezután a második jegyekkel végezzük a mőveletet, figyelembe véve az átvitelbit értékét, tehát ki kell vonni 3-ból 5-öt, valamint a különbségbıl 1-et. Ehhez ismét áthozatra van szükség, vagyis az eredményt 27 + 3 − 5 − 1 = 24 adja, ez lesz az eredmény középsı jegye, és az átvitelbit értéke ismét 1 lesz. Végül az utolsó lépésben a kisebbítendı jegy 2, a kivonandó értéke 1, és az átvitelbit értéke 1, így a számítás 2 − 1 − 1 = 0 , és az átvitelbit értéke 0. Ellenırizve az eredményt láthatjuk, hogy jól számoltunk, pontosabban szólva, a gép a helyes eredményt adja, hiszen 0 ⋅ 27 2 + 24 ⋅ 27 + 9 = 657 = 1541 − 884 . Áttérünk a fixpontos elıjeles számok összeadására, illetve kivonására. Rögtön megállapíthatjuk, hogy a kivonás visszavezethetı az összeadásra, ha meg tudjuk oldani a számok elıjelváltását, vagyis azt kell megnéznünk, hogy egy szám kódjából hogyan tudjuk elıállítani a szám ellentettjének kódját. A továbbiakban feltételezzük, hogy M = ur n −1 , ahol r > u ∈ N és u páros, vagyis a legnagyobb kód értéke ur n −1 − 1 , és a mindhárom fixpontos, elıjeles számábrázolásban elıforduló K értéke, u amely a nem negatív és a negatív számok kódját választja el, K = r n −1 , vagyis M = 2 K , illetve az 2 u n −1 M eltolt nullpontú kód esetén e mellett még lehetséges, hogy K = r − 1 , tehát K = −1. 2 2 Eltolt nullpontú kódolás esetén az ábrázolható számtartomány − K ≤ N ≤ M − K − 1 , és az N szám kódja ϕ en ( N ) = K + N . Ekkor ϕ en (− N ) = K + (− N ) = K + (K − ϕ en ( N )) = 2 K − ϕ en ( N ) . Abban az esetben, ha M = 2 K , akkor ϕ en (− N ) = 2 K − ϕ en ( N ) = M − ϕ en ( N ) , feltéve, hogy az így kapott érték kód, azaz 0 ≤ M − ϕ en ( N ) ≤ M − 1 . Tekintettel arra, hogy 0 ≤ ϕ en ( N ) ≤ M − 1 , a bal oldali egyenu lıtlenség teljesül. Ugyanakkor a jobb oldali feltétel ϕ en ( N ) = 0 -nál, azaz N = − K = − r n −1 esetén 2 nem teljesül. Ha ez volt az eredeti szám, akkor az ellentett kódja nem ábrázolható, és így az ellentett
DIGITÁLIS ARITMETIKA
54
képzésénél úgynevezett túlcsordulás, angolul overflow keletkezik. A túlcsordulás jelzésére egy túlcsordulásflag szolgál az állapotregiszterben. Ez az a flag, amelyet korábban, az állapotregiszter bevezetése során említettünk, mint az ott megadott bitek mellett egy olyat, amely mindig megtalálható a státuszregiszterben. Érdemes megnézni, hogy tulajdonképpen mit is jelent a gépben ez a túlcsordulás. Az eredeti szám negatív volt, így az ellentettje pozitív, és akkor a kódja nagyobb, mint K. Ezzel szemben, amikor a gép képzi az ellentett kódját, akkor közbülsı eredményként M − 0 = M jön létre, ám a gép modulo M számol, azaz a végeredmény (M mod M ) = 0 = ϕ en (− K ) , vagyis egy pozitív szám kódja helyett egy negatív szám kódja lesz. Még azt érdemes figyelembe venni, hogy a maradék(M )
képzéssel együtt általánosan ϕ en (− N ) = (M − ϕ en ( N ) mod M ) = (− ϕ en (N ) mod M ) = ϕ en (N ) , vagyis, ha eltolt nullpontú kódnál M = 2 K , akkor az ellentett eltolt nullpontú kódja az eredeti szám eltolt nullpontú kódjának M-re vonatkozó komplemense. M A másik esetben K = − 1 , és ϕ en (− N ) = ((M − 1) − ϕ en (N )) − 1 . Most ismét keletkezhet 2 M túlcsordulás, nevezetesen akkor, ha az eredeti szám N = . Ennek a számnak ϕ en (M ) = M − 1 a 2 kódja, tehát ϕ en (− N ) = M − 2 − (M − 1) = −1 lenne, e helyett viszont, a maradékolás következtében,
ϕ en ( − N ) = ( −1 mod M ) = M − 1 , vagyis egy pozitív szám ellentettjének kódjaként ismét egy pozitív szám kódját kapjuk. Most nézzük az elıjeles abszolút értékes számábrázolást. Ebben az esetben nagyon egyszerő u u az elıjelváltás. A szám kódja s r n −1 + N , míg ϕ ea (− N ) = (1 − s ) r n −1 + N . Mivel a kód mindkét 2 2 u esetben nem negatív, és kisebb, mint M = ur n −1 , ezért ϕ ea (− N ) = r n −1 + ϕ ea (N ) mod M , és így 2 u nincs más dolgunk, mint a legmagasabb helyiértékő jegyhez hozzáadni -t, az esetleges átvitel figye2 lembevétele nélkül. Ez u = 2 esetén annyit jelent, hogy az elıjelbitet az ellenkezıjére kell váltani. Most nem léphet fel túlcsordulás, ugyanis az ábrázolható számtartomány szimmetrikus a nullára, hiszen a megadott K értékkel − (K − 1) ≤ N ≤ K − 1 . Egyben azt is látjuk, hogy speciális esetben a negatív nullát kapjuk. Végül a komplemens kódot nézzük. Ekkor − K ≤ N ≤ K − 1 , és ϕ k ( N ) = (N mod M ) , tehát (M )
ϕ k (N )
= (− ϕ k ( N ) mod M ) = (− (N mod M ) mod M ) = (− N mod M ) . Tekintetbe véve, hogy (M )
0 ≤ (− N mod M ) < M , tehát ϕ k ( N ) = (− N mod M ) = ϕ k (− N ) , egy szám ellentettjének komplemens kódja az eredeti szám komplemens kódjának a komplemense. Túlcsordulás azonban most is keletkezhet, hiszen a számbrázolás tartománya nem szimmetrikus a nullára, nevezetesen a legkisebb negatív szám ellentettje már nem ábrázolható, így ennek a számnak az ellentett-képzésekor létrejön a túlcsordulás. Konkrétan, a legkisebb ábrázolható szám, − K komplemens kódja 2 K − K = K , és ennek a komplemense (− K mod 2 K ) = K .
Az ellentettképzés egy olyan mővelet, amelynek egy operandusa van, vagyis ez egy egyváltozós, másként unér mővelet. Unér mővelettel találkozunk majd a multiplikatív mőveleteknél is. Miután tisztáztuk az ellentettképzést, áttérhetünk az összeadás vizsgálatára. Ismét három eset van a három fixpontos kódolásnak megfelelıen. Elsıként megint az eltolt nullpontú kódolást vizsgáljuk. Ekkor ϕ en (N 1 ) = K + N 1 , ugyanígy a másik operandusra ϕ en ( N 2 ) = K + N 2 , és ϕ en ( N 1 + N 2 ) = (K + (N 1 + N 2 ) mod M ) . De
Számítógépi matematika
(ϕ en (N 1 ) + ϕ en (N 2 ) − K mod M ) = ((K + N 1 ) + (K + N 2 ) − K = (K + ( N 1 + N 2 ) mod M ) = ϕ en ( N 1 + N 2 )
55 mod M ) =
,
tehát (ϕ en ( N 1 ) + ϕ en ( N 2 ) − K mod M ) = ϕ en ( N 1 + N 2 ) , azaz eltolt nullpontú kódolásnál a kódok összegébıl levonva az eltolást, a maradék az összeg eltolt nullpontú kódja. Vegyük azonban észre, hogy amennyiben a maradék különbözik a maradékolt értéktıl, akkor túlcsordulás lépett fel. Könnyen látható, hogy túlcsordulás csak abban az esetben léphet fel, ha két azonos elıjelő számot adunk össze, ugyanis − K ≤ N 1 ≤ 0 ≤ N 2 ≤ M − K − 1 esetén − K ≤ N 1 + N 2 ≤ N 2 ≤ M − K − 1 (ez a megállapítás független a kódolási formától, tehát igaz az elıjeles abszolút értékes, valamint a komplemens kódra is). Az eltolt nullpontú kódok összeadásánál még emlékeztetünk arra, hogy amennyiben M = 2 K , akkor a szám eltolt nullpontú kódjából egyszerően megkapjuk a szám komplemens kódját úgy, hogy a u legmagasabb helyiértékő jegyhez hozzáadjuk -t az esetleges átvitel negligálásával, és ugyanígy tu2 dunk visszatérni a komplemens kódról az eltolt nullpontú kódra. Ez azért fontos, mert majd látjuk, hogy az összeadás különösen egyszerő a komplemens kód esetén, és akkor ezzel az áttéréssel egyszerő az eltolt nullpontú kódok összeadása is, hacsak a megfelelı feltétel teljesül. Következik az elıjeles abszolút értékes ábrázolás. Itt most azt az esetet nézzük, amikor a gép más kódolási módra való áttérés nélkül, közvetlenül az elıjeles abszolút értékes kódokkal végzi a mőveletet (a valóságban a gépek áttérnek a komplemens kódra, úgy végzik az additív mőveletet, majd az eredményt visszaalakítják az eredeti kódformátumra – hogy miért, kiderül a két kódolásnál szükséges eljárásból). Legyen a két összeadandó N 1 és N 2 , ekkor ϕ ea (N 1 ) = s1 K + N 1 , ϕ ea ( N 2 ) = s 2 K + N 2 ,
és ϕ ea (N 1 + N 2 ) = (sK + N1 + N 2 mod M ) , ahol s az összeg elıjele. N 1 + N 2 = N 1 + N 2 , ha a két szám elıjele azonos, és ekkor s1 = s = s 2 , míg N 1 + N 2 = N1 − N 2 , ha a két szám egyike negatív,
és a másik pozitív. Ez utóbbi esetben az összeg a nagyobb abszolút értékő operandus elıjelét örökli (ha a két abszolút érték azonos, akkor az eredmény 0, és ekkor közömbös az elıjel). Látható, hogy ennél a kódolási formánál a mővelet csak esetszétválasztással hajtható végre, így viszonylag bonyolult (összehasonlítva a következıkben tárgyalandó komplemens kódos összeadással). elıjeles abszolút értékes összeadás ha s1 = s 2 akkor s = s1
N ( a ) = N 1(a ) + N 2(a ) különben ha N 1(a ) ≥ N 2(a ) akkor s = s1 N ( a ) = N 1(a ) − N 2(a ) különben s = s2 N ( a ) = N 2(a ) − N 1(a ) elágazás vége elágazás vége eljárás vége. 1. algoritmus
DIGITÁLIS ARITMETIKA
56
A mővelet algoritmusa a 55. oldalon látható (1. algoritmus). Az eljárásban N (a ) az eredmény, míg N 1(a ) és N 2(a ) a két operandus abszolút értékét jelöli. Amennyiben M = ur n −1 = 2 K , akkor a szám u negatív elıjelő, ha a kódszó legmagasabb helyiértékhez tartozó jegye legalább , ellenkezı esetben a 2 szám nem negatív. Ez utóbbi esetben a szám abszolút értéke maga a kódszó, míg negatív szám esetén a szám kódjából úgy kapjuk meg a szám abszolút értékét, hogy a legmagasabb helyiértékő jegybıl u levonunk . Abban az esetben, ha u = 2 , és bináris kód esetén csak ez lehetséges, akkor a kód bal 2 szélsı jegye egyszerően az elıjelbit, és ezt a jegyet elhagyva megkapjuk a szám abszolút értékét. Az eredménynél visszafelé járunk el: ha az eredmény negatív, akkor u = 2 esetén eléje írjuk az elıjelbitet, míg u > 2 esetén az eredmény n − 1 -indexő jegyéhez (a legalacsonyabb helyiértékő jegy indexe 0!) u negatív eredmény esetén hozzáadunk -t. Mindez mutatja, hogy ebben az esetben az elıjelet és a 2 szám abszolút értékét külön kell kezelni, és az u = 2 esetben az elıjelbit végeredményben véve magában a számolásban nem vesz részt. Hátra van a komplemens kódok összeadása. Ebben az esetben ϕ k (N 1 ) = ( N 1 mod M ) , hasonlóan, ϕ k ( N 2 ) = ( N 2 mod M ) , és ϕ k ( N 1 + N 2 ) = (N 1 + N 2 mod M ) . De korábban már láttuk, hogy tetszıleges u, v és nem nulla t esetén ((u mod t ) + (v mod t ) mod t ) = (u + v mod t ) , vagyis a konkrét esetben
(ϕ k (N1 ) + ϕ k (N 2 )
mod M ) = (( N 1 mod M ) + ( N 2 mod M ) mod M ) =
= ( N1 + N 2 mod M ) = ϕ k ( N1 + N 2 )
,
azaz két szám összegének komplemens kódja a két szám komplemens kódjának az összege, feltéve, hogy nem lép fel túlcsordulás, azaz nincs szükség maradékolásra. Látható, hogy a három kódolási mód közül messze a komplemens kód esetén a legegyszerőbb az összeadás, ami indokolja, hogy a számítógépek a fixpontos számokat szinte mindig komplemens kódolásúnak tekintik, és így végzik a mőveletvégzést. Mint korábban láttuk, az elıjeles abszolút értékes kódolás esetén nehézkes az összeadás. A gép többnyire nem is az ilyen kódokkal végzi az összeadást, hanem áttér komplemens kódra, elvégzi a mőveletet, és az eredményt visszakonvertálja elıjeles abszolút értékes kódra. (Ha még emlékeznek, akkor tudják, hogy nem negatív szám esetén a konvertálás azt jelenti, hogy nem csinálunk semmit, míg negatív szám esetén a szám abszolút értékének vesszük a komplemensét M-re, illetve a másik irányban, vesszük a kód komplemensét M-re, és ez lesz a szám abszolút értéke). Ha még visszalapozunk az additív mőveletek elejére, akkor látjuk, hogy abban a szinte kizárólagos esetben, amikor az operandusok és az eredmény hossza, valamint az r-edespont helye megegyezik, akkor közömbös (az összeadás szempontjából!), hogy hol helyezkedik el az r-edespont. A gépek ismét majdnem kizárólag a fixpontos számokat egésznek tekintik. Fontos észrevennünk, hogy komplemens kódolás esetén a kód valamennyi jegye egyenrangú résztvevıje az összeadásnak, szemben az elıjeles abszolút értékes összeadást, ahol a legmagasabb helyiértékő jegyet másként kezeljük, mint a többi jegyet. Még nézzük meg, hogy komplemens kód esetén hogyan jelentkezik a túlcsordulás. Emlékeztetünk rá, hogy túlcsordulás csak azonos elıjelő számok összeadása esetén léphet fel. Legyen a két opeM M randus nem negatív, azaz 0 ≤ N 1 < K = , 0 ≤ N2 < K = , de K ≤ N1 + N 2 . A két operandus kom2 2 plemens kódja önmaga, és (ϕk ( N1 ) + ϕk ( N 2 ) mod M ) = ( N1 + N 2 mod M ) = N1 + N 2 , ugyanis a feltételek alapján 0 < K ≤ N 1 + N 2 < M . De ebbıl az utolsó egyenlıtlenségbıl azt is látjuk, hogy ez egy negatív számnak, nevezetesen − (M − ( N 1 + N 2 )) -nek a kódja. A másik esetként legyen a két M M = − K ≤ N1 < 0 , − = − K ≤ N 2 < 0 , de N1 + N 2 < − K . Most az opeösszeadandó negatív, azaz − 2 2
Számítógépi matematika randusok kódja
(N 1 + N 2
mod
( N1 mod M ) = M + N1 M ) = M + ( N 1 + N 2 ) , és
57
és (N 2 mod M ) = M + N 2 . − M ≤ N1 + N 2 < − K < 0 , így
(ϕ k (N 1 ) + ϕ k (N 2 ) mod M ) = (M + N1 + M + N 2 mod = ( N1 + N 2 mod M ) = M + (N 1 + N 2 )
M )=
.
M M , így 0 ≤ M + (N 1 + N 2 ) < = K , vagyis a két negatív szám komple2 2 mens kódjának összege a maradékképzés után egy nem negatív szám, M + ( N 1 + N 2 ) kódját adja. − M ≤ N1 + N 2 < − K = −
A gép összeadáskor – és minden más olyan mőveletnél, ahol létrejöhet – automatikusan figyeli a túlcsordulást, és a megfelelı flag beállításával jelzi a túlcsordulást. Komplemens kódolású számok összeadásakor ez például a 2. algoritmussal adható meg. Az eljárásban az összeadást csak jeleztük. OF az Overflow Flag rövidítése.
túlcsordulás( N 1 , N 2 , OF ) OF = 0 ha s1 = s 2 akkor t = s1 OF = 1 elágazás vége összeadás ha OF = 1 akkor ha t = s akkor OF = 0 elágazás vége elágazás vége eljárás vége. 2. algoritmus
A mővelet elvégzése után a gép azt is jelzi, hogy az eredmény negatív-e, vagy nulla. Erre szolgál a zéróflag, ZF , és az elıjelflag SF (az elıjel angolul sign) Ha u = 2 , akkor a legmagasabb helyiértékő jegy az elıjegybit, és ekkor SF = s , ahol s az eredmény elıjegybitje. A két flag állásából az is megállapítható, ha az eredmény pozitív, ekkor ugyanis az eredmény sem nem nulla, sem nem negatív, azaz mindkét flag értéke 0 (egy-egy flag értéke akkor és csak akkor 1, ha az általa jellemzett tulajdonság az utoljára végrehajtott olyan mőveletnél, amelynél ez a tulajdonság értelmezhetı, fennáll, feltéve, hogy idıközben utasítással nem módosítottuk a flag értékét). A lebegıpontos számoknál a számot egy fixpontos számpárral adjuk meg, ahol az egyik komponens a mantissza kódja, míg a másik a kitevı kódja. Ha a két szám α 1 = m1 d k1 és α 2 = m2 d k 2 , m továbbá mondjuk k1 ≤ k 2 , akkor az összeg α 1 + α 2 = m1 d k1 + m 2 d k 2 = k −1 k + m 2 d k 2 . Ezek sze2 1 d rint úgy lehet összeadni a két lebegıpontos számot (pontosabban szólva úgy kapjuk meg a két szám összegének kódját), hogy a kisebb kitevıjő szám mantisszáját addig osztjuk d-vel, és ezzel egyidejőleg addig növeljük ezt a kisebb kitevıt, amíg a két kitevı meg nem egyezik, és ekkor a két mantisszát összeadjuk, és a kitevı a most már közös kitevı. A mantisszát és a karakterisztikát binárisan kódoljuk. Ha d = 2 , akkor a d-vel való osztás egyszerően azt jelenti, hogy a mantissza kódját egy hellyel jobbra léptetjük, és a bal oldalon egy 0 lép be. Ekkor az eredeti mantissza jobb szélsı bitje elvész, hiszen az
58
DIGITÁLIS ARITMETIKA
az eltolás következtében kikerül a regiszterbıl. d = 16 esetén, lévén, hogy 16 = 2 4 , a d-vel való osztás négy bittel való jobbra léptetést jelent, egyebekben az eljárás azonos az elızıvel. Lényeges kiemelni, hogy bár az összeadást úgy is elvégezhetnénk, hogy a nagyobb kitevıjő szám kitevıjét csökkentjük a mantissza egyidejő, d-vel való szorzásával, ám ezt a számítógépben nem tehetjük meg. Ebben az esetben ugyanis a mantisszát balra kellene léptetni egy vagy négy bittel, d-tıl függıen, aminek az lenne a következménye, hogy a szám bal szélsı egy vagy négy bitjét veszítenénk el, amelyek a szám legértékesebb jegyei. Az elıbbi mővelettel még nem fejeztük be a lebegıpontos számok összeadását, ugyanis az eredmény nem feltétlenül normalizált. Ha az összeg nem normalizált, akkor normalizálni kell, feltéve, hogy ez lehetséges. Elıfordulhat, hogy a kitevı már nem növelhetı, illetve nem csökkenthetı, ekkor a végtelent, vagy egy nem normalizált alakú kódot, esetleg a gépi nullát kapjuk. Az összeadás algoritmusa indokolja, hogy a lebegıpontos számok kitevıjét eltolt nullpontú kóddal ábrázoljuk. A lebegıpontos számok kivonása egyszerően a kivonandó ellentettjének a kisebbítendıhöz való hozzáadásával végezhetı, annál is inkább, mert a lebegıpontos számok mantisszája szinte kizárólag elıjeles abszolút értékes kódolású. A BCD-számok összeadásának egy módja, hogy az egyik operandus valamennyi számjegyéhez az összeadás elıtt hatot hozzáadunk, majd az így kapott számhoz mint bináris számhoz hozzáadjuk a másik számot mint bináris számot, és ahol valamely tetrád bal szélsı bitjérıl nincs átvitel a következı bitre, az összeg ezen tetrádjából levonva hatot, megkapjuk az összeg BCD-kódját. A BCDszámok kivonásánál a kisebbítendıbıl mint bináris számból kivonjuk a kivonandót mint bináris számot, majd azon tetrádból, amelynél szükség volt áthozatra, levonunk hatot. Az elıbbi rövid leírás után részletesebben is meg kell vizsgálnunk a lebegıpontos, valamint a BCD-számok összeadását. A lebegıpontos szám egy fixpontos számpár, és a fixpontos számokat már össze tudjuk adni. Figyelembe kell azonban venni, hogy a két szám közvetlenül csak akkor adható össze, ha azonos a karakterisztikájuk. Két lehetıség van: vagy a nagyobb karakterisztikájú számot igazítjuk a kisebb karakterisztikájúhoz, vagy fordítva, és közben a mantisszát megfelelıen alakítva. A papíron való számolásnál a két módszer ekvivalens, ám ez nem igaz a gépre. Legyen a két szám N 1 = m1 d k1 , N 2 = m2 d k 2 , és N1 + N 2 = N = md k , és tegyük fel, hogy k1 < k 2 . Ha k 2 -t eggyel csökkentjük, akkor egyidejőleg a mantisszát d-vel szorozni kell. Amennyiben d = r t , ahol r a mantissza ábrázolásához használt számrendszer alapszáma, akkor a d-vel való szorzás azt jelenti, hogy az r-edes pontot t pozícióval jobbra toljuk (gondoljunk a 10-zel való szorzásra). Igen ám, de a mantissza fixpontos szám, vagyis az r-edespont helye a számot tároló regiszterben rögzített. Vegyük azonban figyelembe, hogy a rögzített számhoz képest eggyel jobbra tolni az r-edes pontot ugyanaz, mint ha a fixen elhelyezkedı r-edesponthoz képest a számot toljuk egy helyiértékkel balra. Amennyiben a mantissza normalizált, és az esetek túlnyomó többségében normalizált, akkor a bal szélsı t jegy közül legalább egy nem nulla, vagyis a mantissza d-alapú számrendszerben való felírása olyan, hogy a megadott hosszon való felírásban a bal szélsı jegye nullától különbözı. Ha most a számot t hellyel balra toljuk, vagyis a d-alapú számrendszerben egy hellyel balra léptetjük, akkor ez a legmagasabb helyiértékő jegy elvész, a mantissza túlcsordul, és teljesen torz eredményt kapunk. Ha viszont a kisebb kitevıjő számot igazítjuk a nagyobb kitevıjőhöz, akkor a kisebb karakterisztika eggyel való növelésével egyidejőleg a mantisszát t pozícióval jobbra toljuk, ami a legkevésbé értékes jegyek elvesztését eredményezi. Ebbıl nyilvánvalóan következik, hogy a gépben ezt az utóbbi módszert alkalmazzuk, vagyis a lebegıpontos számok összeadásakor a kisebb kitevıjő szám kitevıjét mindaddig eggyel növeljük, és ezzel egyidejőleg a mantisszáját t helyiértékkel jobbra léptetjük, amíg a két kitevı különbözik, és amikor már a két kitevı megegyezik, akkor a két mantisszát összeadhatjuk: m1 d k1 + m2 d k 2 = m1 d − (k2 − k1 ) + m2 d k 2 . Ez azonban általában még nem az összeg lebegıpontos alakja, ugyanis ez a szám általában még nem normalizált. Ez mindkét irányban elıfordulhat, azaz lehetséges, hogy m1 d − (k 2 − k1 ) + m 2 < d t −1 , vala-
(
)
mint, hogy m1 d − (k 2 − k1 ) + m 2 ≥ d t . Amennyiben az eredmény mantisszája nem nulla, akkor elméletileg mindig lehetséges a normalizálás, ám a gyakorlatban ez nem mindig igaz, ugyanis a normalizálás so-
Számítógépi matematika
59
rán a karakterisztikát növelni vagy csökkenteni kell. (Könnyen látható, hogy összeadás után a mantiszsza abszolút értéke 2d t -nél, de akkor d t +1 -nél biztosan kisebb, így a kitevıt legfeljebb eggyel kell növelni, ám a másik irányban a legrosszabb esetben a mantissza minden jegye nulla, a legalacsonyabb helyiértékő jegy kivételével). Ám a karakterisztika kódja csak véges sok értéket vehet fel, így elıfordulhat, hogy a kitevı tovább már nem növelhetı, vagy tovább nem csökkenthetı. Ilyen esetben fordul elı a lebegıpontos túlcsordulás, illetve a lebegıpontos alulcsordulás. Bizonyos lebegıpontos számábrázolásnál az olyan lebegıpontos számot, amelynek a karakterisztikája a legnagyobb ábrázolható karakterisztikával egyenlı, vagy annál nagyobb, végtelennek tekintjük, és így is kezeljük. Hasonlóan, ha a lebegıpontos szám kódjában a kitevı a legkisebb ábrázolható érték, vagy annál kisebb, akkor a számot a legkisebb ábrázolható karakterisztikával adjuk meg, ám nem normalizált alakban. Mindkét esetrıl volt szó korábban, a számábrázolással foglalkozó résznél. Az elızı okfejtésbıl látszik, hogy igen gyakran van szükség a lebegıpontos számok karakterisztikáinak összehasonlítására. Valójában a gépben nem a karakterisztika, hanem annak kódja van, így az összehasonlítást a kódokkal kell elvégezni. A két kód összehasonlítása akkor könnyő, ha a kód rendezéstartó, így érthetı, hogy a lebegıpontos számok kitevıjét szinte kizárólag eltolt nullpontú kóddal ábrázoljuk, hiszen ez az egyetlen rendezéstartó fixpontos számábrázolás. Már csak a BCD-ábrázolás van hátra. A kivonáshoz szükséges elıjelváltás itt könnyedén elvégezhetı, ám nem ilyen egyszerő a helyzet az összeadásnál. Ismét általánosabban vizsgáljuk a kérdést. A BCD-ábrázolás speciális esete volt a vegyes alapú számábrázolásnak, vagyis amikor a két alap r1 és r2 , és r1 ≤ r2s , ahol s egy pozitív egész. Ekkor a
n −1
∑i =0 bi r1i
számot – amelyet most egésznek tekinthe-
tünk – fel tudtuk írni úgy, hogy az r1 -alapú számrendszerbeli bi jegyeket az r2 -alapú számrendszerben adjuk meg, nevezetesen bi = ∑ j = 0 a (ji ) r2j , és ekkor s −1
∑i =0 bi r1i = ∑i =0 (∑ j =0 a (ji )r2j )r1i . Ennek a n −1
n −1
s −1
jobb oldalon álló számnak valamennyi jegye az r2 -alapú számrendszer valamely számjegye, tehát a jegyeken az r2 -alapú számrendszer mőveleteit kell végezni, ám maga a szám az r1 -alapú számrendszerben van megadva, tehát ennek a szabályai szerint kell a mővelet végeredményét megadni. A BCD esetén r1 = 10 , r2 = 2 , és s = 4 . Az összeadásnak több módja van, az egyik például néhány jegyen végzi az összeadást az r2 alapú számrendszerben, majd az így kapott eredményen elvégzi a szükséges korrekciót. Ennek az a hibája, hogy ha a néhány jegy több, mint egy jegy, akkor a korrekció vagy esetszétválasztással jár, vagy a korrekció után ismét szükség lehet egy korrekcióra. Például legyen a két összeadandó érték 35 és 67, ekkor az összegük 102. A két számnak megfelelı BCD-szám hexadecimális felírása 3516 és 6716 . Összeadva ezt a két hexadecimális számot, az eredmény 9C16 . A bal oldali jegy kisebb, mint 10, tehát ez érvényes BCD-számjegy, ám a jobb oldali jegy nagyobb, mint 9, ezért ez így nem BCDszám, korrekcióra van szükség. Ha ehhez a jegyhez 6-ot hozzáadunk, akkor az eredmény A216 . Látjuk, hogy a jobb oldali jegy már BCD-jegy, sıt, a helyes végeredmény jobb oldali jegyével azonos, ám most elromlott a bal oldali jegy. Hozzáadva a bal oldali jegyhez 6-ot, az eredmény 102 16 lesz, és ez a szám mint egy BCD-szám, a 102 decimális számnak felel meg, amely a helyes eredmény. Mi most egy másik módszert ismertetünk, egy olyat, amelyben nincs szükség a korrekció korrekciójára, sem pedig esetszétválasztásra. Ezt a módszert többek között nagy IBM-gépeken alkalmazzák. Elsıként tekintsük az azonos elıjelő számok összeadását. Mielıtt a két számot a gép összeadná, az egyik operandus valamennyi jegyéhez hozzáad r2s − r1 -et, a BCD esetén 6-ot. Legyen a két ope-
randus i-edik jegye az eredeti felírásban Ai és Bi , ekkor 0 ≤ Ai < r1 , és így Ai + (r2s − r1 ) < r2s , ahol ′ most Ai = Ai + r2s − r1 az r2s -alapú számrendszer egy jegyének is tekinthetı. Mivel r2s az r2 pozitív egész kitevıs hatványa, ezért a két alap esetén a mőveletek lényegében véve azonosak. Ha a mőveletet az r2 -alapú számrendszerben végezzük, akkor csupán annyi az eltérés, hogy az átvitelek közül minden
(
)
s-edik lesz átvitel az r2s -alapú számrendszerbeli összeadás esetén. Legyen ez utóbbi átvitel az i-edik pozícióra Ti , és az i-edik pozíción keletkezı átvitel Ti +1 . Tegyük fel, hogy az r1 -alapú számrendszer-
DIGITÁLIS ARITMETIKA
60
ben végezve az összeadást, az i-edik pozícióra az átvitel C i , az ezen pozíción keletkezı átvitel C i +1 , és Ai + Bi + C i = C i +1 r1 + S1 . Mivel mind C −1 , mind T−1 0, ezért C −1 = T−1 . Most legyen egy i-re ′ C i = Ti . Az i-edik helyen ekkor Ai′ + Bi + C i lesz az eredmény. Mivel r2s − r1 ≤ Ai ≤ r2s − 1 , 0 ≤ Bi ≤ r1 − 1 , valamint 0 ≤ C i ≤ 1 , ezért r2s − r1 ≤ Ai′ + Bi + C i ≤ r2s + r1 − 1 < r2s + r1 ≤ 2r2s , így az
összeadás eredménye Ai′ + Bi + C i = Ti +1 r2s + Di , ahol Ti +1 0 vagy 1, és 0 ≤ Di < r2s . Ha Ti +1 = 1 , akkor Ai + r2s − r1 + Bi + C i = r2s + Di , és ebbıl Ai + Bi + C i = r1 + Di . Ai , Bi és C i korlátait figyelembe véve r1 + Di = Ai + Bi + C i ≤ r1 − 1 + r1 − 1 + 1 = 2r1 − 1 < 2r1 , tehát Di < r1 . Összehasonlítva C i +1 r1 + S1 = Ai + Bi + C i = r1 + Di = 1 ⋅ r1 + Di két oldalát, S i = Di és C i +1 = Ti +1 = 1 . Ha viszont ′ Ti +1 = 0 , akkor r2s > Ai + Bi + C i = Di ≥ r2s − r1 , és innen r1 > Ai + Bi + C i = Di − r2s − r1 ≥ 0 , tehát
(
)
(
)
S i = Di − r2s − r1 , és C i +1 = Ti +1 = 0 , vagyis le kell vonni az összeg megfelelı jegyébıl azt az értéket, amit az összeadás elıtt az egyik operandus jegyéhez hozzáadtunk. Azt látjuk tehát, hogy amennyiben egy r2s -beli jegynél átvitel keletkezik a következı jegy felé, akkor az ezen az r2s -beli pozíción keletkezı eredmény megegyezik az r1 -beli összeadás eredményével. Ha viszont nincs átvitel, akkor a keletkezett r2s -beli számjegy éppen annyival több az r1 -beli összeg megfelelı jegyénél, amennyit az összeadás elıtt az egyik operandushoz hozzáadtunk, így ezt a korrekciós értéket most az összeg megfelelı jegyébıl le kell vonni. A BCD esetén tehát az egyik operandus minden jegyéhez az összeadás elıtt 6-ot hozzáadunk, elvégezzük a bináris összeadást, és ha valamelyik tetrádnál nincs átvitel, akkor az összeg ezen pozícióján álló jegyébıl levonunk 6-ot. Például legyen a két operandus 834 és 327, és a megfelelı két BCD szám formailag ugyanez, ha a jegyek bináris tetrádjait hexadecimálisan írjuk fel. Adjunk az elsı szám mindenegyes jegyéhez hatot, akkor az eredményül kapott hexadecimális szám E 9 A16 . Adjuk most össze ezt a számot, valamint 327 16 -ot mint hexadecimális számokat. Az eredmény 11C116 , ahol aláhúzással jelöltük, hol keletkezett átvitel. Most azon az egy pozíción, ahol nincs átvitel (a bal szélsı 1 már egy átvitel eredménye!), levonunk 6-ot, és akkor az 1161 BCD számot kapjuk. De 834 + 327 = 1161 , ami mutatja, hogy a módszerünk helyes eredményt adott. A kivonás valamivel egyszerőbb az összeadásnál. Egyszerően kivonjuk a vegyes formában megadott két számot az r2 -alapú számrendszerben, és amelyik r2s -beli pozíción volt áthozat, ott az eredmény megfelelı r2s -beli jegyébıl levonunk r2s − r1 -et. Hogy így a helyes eredményt kapjuk, az az összeadás alapján már könnyen ellenırizhetı. A BCD esetén a két BCD számmal mint bináris számmal elvégezzük a kivonást, és amelyik tetrádnál volt áthozat, ott a keletkezett tetrádból levonunk 6-ot. Igazolásként vegyük tekintetbe, hogy az i-edik pozíción a korrekció elıtt C i +1 ⋅ 16 + Ai − Bi − C i áll. Abban az esetben, ha C i +1 = 0 , akkor Ai − Bi − C i ≥ 0 , tehát az eredmény decimálisan is helyes. Ha viszont az áthozat értéke 1, akkor Ai − Bi − C i < 0 , tehát decimálisan is szükség van áthozatra, és ebben az esetben (1 ⋅ 16 + Ai − Bi − C i ) − 6 = 1 ⋅ 10 + Ai − Bi − C i , ami éppen a helyes decimális érték. Például az elıbbi két szám esetén 83416 − 327 16 = 50 D 16 , ahol az aláhúzás azt jelöli, hogy annál a pozíciónál szükség volt áthozatra, ezért itt levonunk 6-ot, míg a többi jegyet változatlanul hagyjuk, így az 507 BCD eredményt kapjuk, vagyis 507-et, ami a helyes eredmény. Áttérünk a multiplikatív mőveletekre. Itt az alapvetı probléma, hogy ha két nem nulla számot összeszorzunk, akkor az eredmény abszolút értékében mind az egész rész, mind a törtrész jegyeinek száma a két operandus abszolút értéke megfelelı része jegyeinek összege (pontosabban szólva a törtrész maximum akkora, míg az egész rész vagy ilyen hosszúságú, vagy eggyel kevesebb jegybıl áll), vagyis az eredmény nem fér el az eredeti operandusok hosszában. Ha a két operandus valódi tört, akkor csak a törtrész csonkolódik, tehát az eredmény legkevésbé értékes jegyei vesznek el, ezzel szemben, ha az egész rész nem 0, akkor a bal oldalon (is) elvesznek jegyek, és ezek a jegyek az eredmény legértékesebb jegyei, vagyis az eredmény teljesen torz lesz. Ez mutatja az egyik lehetséges megoldást, nevezetesen, hogy a két operandus legyen törtszám. Ezt a megoldást alkalmazzák általában a lebegı-
Számítógépi matematika
61
pontos számoknál, ahol ennek egyéb indoka is van. A másik lehetséges megoldás, hogy az eredmény kétszer akkora hosszon keletkezik, mint az eredeti operandusok hossza. Abban az esetben, amikor az operandusok egészek, de az abszolút értékük olyan kicsi, hogy még a szorzat is elfér a megadott eredeti hosszon, akkor természetesen nincs szükség az eredmény tárolásánál a kétszeres hosszra. Elıjel nélküli szám kettıvel való szorzása egyszerően annyiból áll, hogy a számot egy bittel balra léptetjük, és a jobb szélen egy 0-t léptetünk be. Ha az eredeti szám bal szélsı bitje egy volt, akkor ez a bit elvész, pontosabban szólva az átvitelbitbe lép be. A kettıvel való osztás egy jeggyel való jobbra léptetés, ekkor balról lép be egy 0, míg a korábbi jobb szélsı bit elvész. Az eltolt nullpontú kódot csak a lebegıpontos számok mantisszájának kódolására használjuk, és a kitevıket nem szükséges szorozni, így ezzel nem foglalkozunk (egyébként abban az esetben, amikor az n-bites kódban az eltolás értéke 2 n −1 , akkor, mint tudjuk, az eltolt nullpontú kód és a komplemens kód a bal szélsı bitben és csak ebben különbözik, így az ilyen eltolt nullpontú kód esetén a szorzás is könnyen végrehajtható). Az elıjeles abszolút értékes kódok szorzása lényegében véve azonos az elıjel nélküli számok szorzásával, hiszen ennél a kódolásnál a bal szélsı bit az elıjel, és ezt elhagyva, a többi bit által meghatározott szám a kódolt szám abszolút értéke. Más a helyzet a komplemens kód esetén. A gyakorlatnak megfelelıen feltesszük, hogy a kódolt szám egész szám. Elıször azt az esetet nézzük, amikor az eredmény hossza megegyezik a két operandus közös hosszával. Ekkor
(ϕ (N ) ⋅ ϕ (N 1
2
)
) ((
)(
)
)
mod 2 n = N 1 mod 2 n N 1 mod 2 n mod 2 n =
(
)
= N 1 N 2 mod 2 n = ϕ (N 1 N 2 )
,
tehát ebben az esetben a kódok szorzata a szorzat komplemens kódja (de ez csak azért igaz, mert feltettük, hogy a szorzat benne van a megengedett tartományban). A másik esetben a szorzat kétszeres hosszon keletkezik. Ebben az esetben
(ϕ ( ) (N ) ⋅ ϕ ( ) (N ) mod n
n
1
2
2 2 n ) = ϕ (n ) (N 1 ) ⋅ ϕ (n ) ( N 2 ) = (s1 2 n + N 1 )(s 2 2 n + N 2 ) =
= (s1 s 2 − s )2 2 n + (s1 N 2 + s 2 N 1 ) 2 n + (s 2 2 n + N 1 N 2 ) =
= ((s1 s 2 − s )2 n + (s1 N 2 + s 2 N 1 ))2 n + (s 2 2 n + N 1 N 2 ) =
.
= ((s1 s 2 − s )2 n + (s1 N 2 + s 2 N 1 ))2 n + ϕ (2 n ) (N 1 N 2 )
Az eredmény akkor adja a szorzat kódját, ha
((s s
1 2
− s )2 n + (s1 N 2 + s 2 N1 ))2 n a 2 2 n egész számú
többszöröse, azaz, ha (s1 s 2 − s )2 n + (s1 N 2 + s 2 N1 ) = k 2 n egy egész k-val. Ha mindkét operandus pozitív, vagy az egyik nulla – és ekkor a másik akár negatív is lehet – , akkor a bal oldalon 0 áll. Ha például N 1 < 0 < N 2 , akkor s1 = 1 , s 2 = 0 és s = 1 , vagyis (s1 s 2 − s )2 n + (s1 N 2 + s 2 N 1 ) = −2 n + N 2 , és ekkor garantáltan nem a helyes eredményt kapjuk, ugyanis ennél az esetnél a pozitív operandusra 0 < N 2 < 2 n , tehát − 2 n < (s1 s 2 − s )2 n + (s1 N 2 + s 2 N1 ) < 0 . Végül ha mindkét operandus negatív, akkor (s1 s 2 − s )2 n + (s1 N 2 + s 2 N 1 ) = 2 n + ( N 2 + N1 ) , hiszen s1 = 1 = s 2 , és s = 0 . − 2 n ≤ N 1 + N 2 < 0 ból azt kapjuk, hogy 0 ≤ 2 n + ( N 2 + N 1 ) < 2 n , és ez akkor lesz a 2 n egész számú többszöröse, ha 2 n + (N 2 + N 1 ) = 0 , ami pontosan akkor teljesül, ha mindkét operandus − 2 n −1 , a legkisebb megengedett érték. Összefoglalva, ha a komplemens kóddal adott számok szorzata kétszeres hosszon keletkezik, úgy akkor és csak akkor kapjuk a kódok szorzataként a szorzat komplemens kódját, ha vagy mindkét szám nem negatív, vagy az egyik szám nulla, vagy mindkét szám a legkisebb ábrázolható szám. Mivel minden esetben helyes eredmény kell, három dolgot tehetünk: 1. szorzás elıtt mindkét számot átalakítjuk elıjeles abszolút értékes kóddá, elvégezzük a szorzást, és a kétszeres hosszúságú eredményt visszaalakítjuk komplemens kódolásúvá; 2. összeszorozzuk a két kódot, és az eredményt korrigáljuk ((s1 s 2 − s )2 n + (s1 N 2 + s 2 N1 ))2 n -nel; 3. a szorzás elıtt átírjuk mindkét kódot 2n -bites kóddá, és így végezzük a kódok összeszorzását.
DIGITÁLIS ARITMETIKA
62
A harmadik eset a helyes eredményt adja, hiszen a kétszeres hosszon a szorzat biztosan elfér, és ekkor a szorzat már azonos hosszúságú a két operandus komplemens kódjának hosszával. A kétszeres hosszra való kiterjesztés egyszerően annyit jelent, hogy a komplemens kódolású szám elıjegybitjét, azaz bal szélsı bitjét írjuk a kiterjesztés valamennyi bitjébe. A második módszer nem praktikus, míg az elsı módszer a legáltalánosabban használt. A harmadik módszerrel az a probléma, hogy a szorzás elvégzéséhez mindkét operandust, és az eredményt is, egy-egy kétszeres hosszúságú tárolóban kell elhelyeznünk. Ezzel szemben az elsı eljárásnál az egyik operandust az eredmény tárolására használt regiszter jobb felében helyezhetjük el, így ez a módszer lényegesen takarékosabb, mint a harmadik. Most nézzük az elıjel nélküli számok szorzását, amikor az eredmény kétszeres hosszon keletkezik. Ez egyben az elıjeles abszolút értékes számok szorzása is, hiszen ekkor az elıjelbit helyére nullát írva a szám abszolút értékének kódját kapjuk, és az eredmény elıjele csak az elıjelektıl, az abszolút értéke csak az abszolút értékektıl függ. Végül ugyanez a módszer akkor is, ha a számok komplemens kódolásúak, és a szorzáshoz az elsı vagy a második módszert alkalmazzuk. Ekkor az egyik operandust beírjuk az eredményt befogadó regiszter jobb oldali, alacsonyabb értékő felébe, míg a bal oldali, értékesebb részre csupa 0-t írunk. Legyen a két operandus külön-külön n-bites, és az eredményregiszter 2n -bites. Az eljárás n lépésbıl, és egy plusz lépésbıl áll. Az n lépés mindegyikében egy hellyel jobbra léptetjük a teljes, 2n -bites eredményregisztert, és ha a jobb oldalon kilépı bit 1, akkor a másik operandust hozzáadjuk az eredményregiszter felsı n bitjéhez. Az n-edik lépés után még egyszer elléptetjük egy bittel jobbra az eredményregisztert, és ekkor ebben a regiszterben a szorzat abszolút értéke áll. Ha a két operandus elıjel nélküli volt, akkor ez már a végeredmény, különben a bal szélsı bitbe beírjuk az eredmény matematikailag helyes elıjelbitjét, illetve komplemens kódolás esetén az elsı módszernél az elıbbi eredménynek vesszük a 2n jegyre vett komplemensét, ha az eredmény matematikailag negatív, míg a második módszer alkalmazásakor végrehajtjuk a szükséges korrekciót. A lebegıpontos számok szorzása egyszerő. Összeszorozzuk a két mantisszát mint fixpontos számot, és összeadjuk a két kitevıt mint fixpontos számot. A szorzat azonban nem biztos, hogy normalizált. Ha a nem nulla mantisszát úgy ábrázoljuk, hogy d t −1 ≤ m < d t , ahol t egész szám, és egyik operandus sem nulla, akkor d 2t − 2 ≤ m1 m 2 < d 2t , így a normalizáláshoz a mantisszát a d-alapú számrendszerben t − 1 vagy t pozícióval kell eltolni. Ebbıl látszik, hogy a legjobb választás vagy t = 0 , vagy t = 1 . Az elıbbi esetben d −1 ≤ m < 1 , a másodikban 1 ≤ m < d , és ez a két szokásos választás. A BCD-számok szorzását majd az általános vizsgálat során tekintjük át. Az osztással csak röviden foglalkozunk. A fixpontos számok esetén láttuk, hogy az eredmény gyakran kétszeres hosszon keletkezik. Ennek megfordítása, amikor egy kétszeres hosszúságú számot osztunk egy egyszeres hosszúságú számmal. Ez az osztás maradékos osztás, hiszen a fixpontos számokat egésznek tekintjük. A hányados a kétszeres hosszúságú szám alsó felében, míg a maradék a felsı felében keletkezik úgy, hogy a maradék nem negatív, míg a hányados a matematikai elıjelnek megfelelı. Ugyanakkor a lebegıpontos számok mantisszája vagy egy egész jegyet tartalmaz, vagy olyan tört, amely legmagasabb helyiértékő jegye nem nulla (mindkét esetben a d-alapú számrendszerben), és így a lebegıpontos számok osztásánál a matematikai hányados áll, természetesen az esetleges további, alacsonyabb helyiértékő jegyek elhagyásával. Az általános eset vizsgálatát ismét elvi kérdésekkel kezdjük, és utána térünk át az egyes ábrázolási módok áttekintésére. A szorzat elıjele az elıjelszabály alapján könnyen meghatározható, ezért elegendı a számok abszolút értékére figyelni. Legyen N1 = ∑i =1 − m1 ai(1)r i és N 2 = ∑i =2 − m 2 ai(2 )r i , ahol m1 és m2 egyn − m −1
n − m −1
1
2
n1 −1
(1)
mástól függetlenül akár negatív is lehet. r N1 = ∑i =0 ai −m1 r < r , tehát r m1 N1 az r n1 -nél kisebb m1
i
n1
(
)(
)
nem negatív egész szám, és hasonlóan kapjuk, hogy r n2 > r m2 N 2 ∈ N . Ekkor r m1 N1 r m2 N 2 is nem
(
)(
)
negatív egész szám, továbbá r m1 N1 r m2 N 2 < r n1 + n2 , tehát N1 N 2 = ∑
(n1 + n2 )− (m1 + m2 )−1 ai r i , így a szorzat i = − ( m1 + m2 )
felírható legfeljebb n1 + n2 jeggyel úgy, hogy a szükséges „tört jegyek” száma maximum m1 + m2 . Ha
Számítógépi matematika
63
N1 = r − m1 , és N 2 = r − m2 , akkor N1 N 2 = r − (m1 + m2 ) , tehát a szorzat hibamentes ábrázolásához szükség van m1 + m2 pozícióra a „tört jegyek” ábrázolásához. Ugyanakkor abban a másik esetben, amikor N 1 = r n1 −1− m1 és N 2 = r n2 −1− m2 , akkor N1 N 2 = r ((n1 + n2 )−1−(m1 + m2 ))−1 , tehát a szorzat megjelenítéséhez legalább n1 + n2 − 1 jegy kell. Most még tegyük fel, hogy r m1 N 1 ≤ v1 r n1 −1 − 1 , és r m2 N 2 ≤ v 2 r n2 −1 − 1 , ahol r ≥ v1 ∈ N + , és r ≥ v 2 ∈ N + . Azt már láttuk, hogy a szorzathoz biztosan szükség van n1 + n2 − 1 jegyre, de n1 + n2 már elegendı. Kérdés, hogy vajon szükség van-e az utóbbi nagyobb értékre. Ez akkor szükséges, ha a két maximális szám szorzata legalább r n1 +n2 −1 . Az elıbbi maximális értékekkel, mindkét oldalt osztva r n1 +n2 − 2 -vel, azt kapjuk, hogy akkor és csak akkor van szükség a nagyobb v v 1 1 1 hosszra, ha r ≤ v1 − n −1 v 2 − n −1 = v1v 2 − n 1−1 − n 2−1 + n + n − 2 . Innen rögtön látszik, hogy 1 2 2 1 1 r r r r r 2 ha v1 v 2 ≤ r , akkor biztosan elég a rövidebb hossz, míg ha mindkét operandus hossza legalább 3, és v +v v v 1 2 v1 v 2 ≥ r + 1 , akkor v1 v 2 − n 1−1 − n 2−1 + n + n − 2 > r + 1 − 1 2 2 ≥ r + 1 − ≥ r , tehát szükség van a r r r 2 r 1 r 1 2 1 1 nagyobb hosszra. Ugyanakkor v1 − n −1 v 2 − n −1 ≥ (v1 − 1)(v 2 − 1) , hiszen pozitív egész n ese1 r r 2 1 tén n −1 ≤ 1 , és ebbıl következik, hogy ha (v1 − 1)(v 2 − 1) ≥ r , akkor nem elég a rövidebb hosszúság. r Most nézzük azokat az eseteket, amikor legalább az egyik hossz legfeljebb 2. Ha mindkét operandus 1 1 hossza 1, akkor a v1 − n −1 v 2 − n −1 ≥ (v1 − 1)(v 2 − 1) kifejezésben egyenlıség áll, tehát ekkor nem csak 1 2 r r elégséges, de szükséges is a (v1 − 1)(v 2 − 1) ≥ r feltétel a nagyobb hosszhoz. A továbbiakban a szimmetria miatt feltehetjük, hogy n1 ≥ n 2 , vagy n1 = n 2 és v1 ≥ v 2 .
v −1 1 1 1 Amennyiben n1 > n 2 = 1 , akkor v1 − n −1 v 2 − n −1 = v1 − n −1 (v 2 − 1) = v1 (v 2 − 1) − 2n −1 . Mi1 2 1 r r r r1 v −1 1 1 r vel 0 ≤ 2n −1 < n −1 ≤ 1 (ugyanis n1 > 1 ), ezért v1 (v 2 − 1) − 1 < v1 − n −1 v 2 − n −1 ≤ v1 (v 2 − 1) . Ha most 1 r r 2 r r 1 1 v1 (v 2 − 1) ≥ r + 1 , akkor r ≤ v1 − n −1 v 2 − n −1 , a szorzathoz n1 + n 2 − 1 jegy kell. Az ellenkezı esetben 1 r r 2 v −1 v1 (v 2 − 1) ≤ r . Itt egyenlıség pontosan akkor van, ha 2n −1 = 0 , vagyis ha v 2 = 1 , és ekkor a második operanr dus 0, így a szorzathoz akár egyetlen pozíció is elég, tehát a rövidebb hossz is biztosan elegendı, ezért a továb1 1 biakban feltehetjük, hogy a jobb oldalon is szigorú egyenlıtlenség áll. Ekkor v1 − n −1 v 2 − n −1 < r , és a 1 r r 2 szorzat ismét elfér a rövidebb hosszon is. Összevonva látjuk, hogy ha n1 > n 2 = 1 , akkor pontosan akkor van 1
1
1
szükség a nagyobb hosszra, ha v1 (v 2 − 1) ≥ r + 1 .
v + v2 1 1 1 1 ≥ v1 v 2 − 2 , Amennyiben n 2 = 2 , akkor v1 − n −1 v 2 − n −1 ≥ v1 − v 2 − > v1v 2 − 1 1 2 r r r r r így ha v1 v 2 ≥ r + 2 , akkor biztosan szükség van a maximális hosszra. Nézzük meg, mi a helyzet, ha v1v 2 = r + 1 . v1 + v 2 v + v2 1 1 = r +1− 1 ≥ r , akkor v1 − n −1 v 2 − n −1 > r , tehát r ≥ v1 + v 2 esetén 1 r r r r 2 szükség van a nagyobb hosszra. A két feltételbıl (v1 − 1)(v 2 − 1) ≥ 2 , és ez pontosan akkor igaz, ha mind v1 , Amennyiben v1v 2 −
mind v 2 legalább 2, és legalább az egyikük nagyobb 2-nél. Ekkor tehát a szorzáshoz nem elég a rövidebb hossz. Most legyen (v1 − 1)(v 2 − 1) < 2 . Ekkor v1 és v 2 legalább egyike, mondjuk v 2 , egyenlı 1-gyel, vagy mindkettı
1 1 2. Az elıbbi esetben v1 − n −1 v 2 − n −1 < v1 ≤ r 1 r r 2
(ha v 2 = 1 , akkor N 2 legmagasabb helyiértékő jegye
DIGITÁLIS ARITMETIKA
64
csak 0 lehet, tehát N 2 valójában csak legfeljebb n 2 − 1 hosszúságú, és akkor a szorzathoz nyilván elegendı
1 1 25 < 3 , elég a kisebb hossz. n1 + n 2 − 1 jegy). A másik esetben r = 3 . Ha n1 = 2 , akkor 2 − 2 − = 3 3 9 1 1 1 1 85 > 3 , tehát a szorzathoz a nagyobb Amennyiben viszont n1 > 2 , akkor 2 − n −1 2 − ≥ 2 − 2 − = 1 3 9 3 27 3 hosszúságra van szükség. Összefoglalva, az r-alapú számrendszerben megadott két szám szorzatához, ahol a legmagasabb helyiértéken álló számjegy kisebb, mint v1 illetve v 2 , pontosan akkor van szükség a két operandus hosszának összegével megegyezı hosszúságú regiszterre, ha
•
(v1 − 1)(v2 − 1) ≥ r , vagy n1 > 1 és v1 (v 2 − 1) ≥ r + 1 , vagy
•
n 2 ≥ 2 és v1 v 2 ≥ r + 2 , vagy
•
n 2 ≥ 2 és r ≠ 3 és v1v 2 ≥ r + 1 , vagy n1 > n 2 ≥ 2 , és v1v 2 ≥ r + 1 .
•
•
A felsorolás lényege, hogy ha a két operandus egyike legalább három-, és a másik minimum kétjegyő (és normális körülmények között egy számítógépben ez általában teljesül), akkor a szorzáshoz pontosan akkor van szükség a két operandus hosszának összegével megegyezı hosszúságú regiszterre, ha v1 v 2 ≥ r + 1 . Ha az operandusok elıjel nélküli számok, akkor r m1 N 1 maximális értéke u1 r n1 −1 − 1 , r m2 N 2 lehetséges legnagyobb értéke u 2 r n2 −1 − 1 , és általában u1 = r = u 2 , vagyis v1 = r = v 2 . Ha viszont elıjeles számokat ábrázolunk, akkor korábbi feltételünk szerint mind u1 , mind u 2 r-nél nem nagyobb páros pozitív egész szám, és ha
u M , akkor a két operandus abszolút értékére r m1 N 1 maximális értéke 1 r n −1 − 1 , r m N 2 lehetséges legna2 2 u 2 n −1 u1 u2 gyobb értéke r − 1 , vagyis ekkor v1 = , v2 = . Elıjeles számok ábrázolása esetén a két célszerő vá2 2 2 r lasztás u = 2 , és így v = 1 , amikor u lényegében véve csupán az elıjelet jelöli, illetve u = 2 , vagyis u a fel2 r tételeknek megfelelı lehetı legnagyobb érték, és ekkor v = . Vessük egybe az elıbbi eredményeket a mos2 tani feltételekkel.
K=
2
1
2
• Amennyiben v = r , akkor (v1 − 1)(v 2 − 1) = (r − 1) , és ha r ≥ 3 , akkor (r − 1) ≥ 2(r − 1) > r , tehát kell a nagyobb hosszúság. Ha viszont r = 2 , és legalább az egyik hossz 1, akkor az 1-hosszúságú tényezı legfeljebb 1, és a szorzat legfeljebb a másik tényezıvel azonos, így ez elfér a rövidebb hosszon is. Ám 2
(3 ⋅ 2 )
n1 − 2 2
2
= 9 ⋅ 2 2 n − 4 ≥ 8 ⋅ 2 2 n − 4 = 2 2 n −1 , így ha mindkét tényezı legalább 2 hosszúságú, akkor ez mutatja, hogy a szorzathoz a nagyobb hosszra van szükség. • Ha elıjeles számoknál u1 = 2 = u 2 , akkor v1 = 1 = v 2 , tehát a szorzathoz a tényezık bármilyen értéke 1
1
1
esetén elegendı az n1 + n 2 − 1 hosszúság (ez, mint már láttuk, nyilvánvaló, hiszen ebben az esetben a két operandus valójában csak legfeljebb n1 − 1 - és n 2 − 1 -jegyő). 2
2
u u r r r r • Elıjeles számok esetén v1v 2 = 1 2 ≤ . Mivel ≤ , ezért ha ≤ r , vagyis ha r ≤ 4 , 2 2 2 2 2 2 2
r akkor mindig elegendı a rövidebb hossz, és ha r = 5 , még akkor is igaz, hogy ≤ r , tehát ekkor 2 sem lehet a szorzat hossza a két hossz összege (mivel bináris és ternáris számok esetén u csak 2 lehet, ezért ezekben az esetekben ezt az eredményt már korábban megkaptuk). r = 8 és r = 9 esetén
Számítógépi matematika
65
2
r − 1 ≥ r , és ha egy r ≥ 8 -ra igaz az elıbbi egyenlıtlenség, akkor indukció alkalmazásával 2 2
2
2
r + 2 r r r − 1 = − 1 + 1 = − 1 + 2 ⋅ − 1 + 1 ≥ r + 2 2 2 2 2 r mutatja, hogy ha r ≥ 8 és v1 = = v 2 , akkor nem elegendı a kisebb hosszúság. 2 r • r = 6 és r = 7 esetén = 3 , így v1 v 2 = 9 ≥ r + 2 , tehát ha mindkét operandus legalább kétjegyő, ak2 kor szükséges a nagyobb hossz. Ugyanakkor v1 (v 2 − 1) = 3 ⋅ 2 = 6 < r + 1 , ami azt jelenti, hogy ha legalább az egyik operandus legfeljebb egyjegyő, akkor a szorzat elhelyezhetı a kisebb hosszon is.
A most kapott eredmény lényege azt mutatja, hogy két olyan számot összeszorozva, amelyek külön-külön elférnek a gép által biztosított hosszúságon, általában „kilógnak” ebbıl a méretbıl, vagyis két n-jegyő szám szorzata nem fér el n pozíción. Ha két azonos nagyságrendő számot szorzunk, úgy az n
eredmény csak akkor tárolható n hosszúsággal, ha a két operandus nem nagyobb r n = r 2 -nél. Csak hogy jobban érzékeljük a problémát, legyen például r = 2 , és n = 16 . Ekkor a legnagyobb ábrázolható egész szám 16383, ám a legnagyobb olyan egész, amelynek a négyzete még befér a 16-bites tárolóba, mindössze 255. A probléma megoldására két út is kínálkozik. Ha az operandusok tört számok, vagyis mindkét operandus abszolút értéke kisebb, mint 1, akkor a szorzat is valódi tört lesz, és csak a törtrész jobb szélsı jegyei, vagyis a legkevésbé értékes jegyek vesznek el, ami „csak” a pontosság rovására megy, de nem okoz katasztrofális hibát. Ez annál is inkább így van akkor, ha az operandusok eleve kerekítés eredményei, vagyis a mőveletben résztvevı adatnak magának is van valamekkora hibája. Ha a két operandus relatív hibája h1 és h2 , továbbá mondjuk h1 ≥ h2 , akkor a szorzat hibája is legalább h1 , vagyis nem érdemes ennél nagyobb pontossággal ábrázolni. Legyen ugyanis α1 és α 2 relatív hibája h1 és h2 . Ekkor a helyes értékekre α − α~ ≤ α h és α − α~ ≤ α h , vagy másként α (1 − h ) ≤ α~ ≤ α (1 + h ) , és hasonló1
1
1 1
2
2
2 2
1
1
1
1
1
an, α 2 (1 − h2 ) ≤ α~2 ≤ α 2 (1 + h2 ) . A két szám szorzata α1α 2 (1 − h1 )(1 − h2 ) ≤ α~1α~2 ≤ α1α 2 (1 + h1 )(1 + h2 ) , és innen α α − α~ α~ ≤ α α (h + h + h h ) , vagyis a szorzat relatív hibája h + h + h h ≥ h . Ha a 1
2
1
2
1
2
1
2
1
2
1
−m
2
1
2
1
r = r − n , tehát az eredn− m r ményt is csak ilyen pontossággal várhatjuk, ami azt jelenti, hogy az eredményben sem érdemes n-nél több értékes jeggyel számolni, ami valódi tört esetén éppen azt jelenti, hogy az m-edik törtjegytıl jobbra álló jegyek értéktelenek. Ha a szám valódi tört, akkor viszont, amint már említettük, az egész részen nincs jegyvesztés, tehát a szorzat pontossága legalább akkora, mint a két tényezı pontossága. Mivel a tudományos-technikai számítások során a mőveletek jelentıs része szorzás, ezért érthetı, hogy a lebegıpontos számok mantisszája úgy normalizált, hogy vagy a d-edespont utáni elsı jegy nem nulla, vagy a mantissza egy egész jegyre van megadva. Ez más szóval azt jelenti, hogy ha a normalizálás a nem nulla számra d t −1 ≤ m < d t , akkor t értéke vagy 0, vagy 1 (ennek a választásnak egyéb elınyei is vannak, amirıl késıbb még lesz szó). Másként szólva, a normalizált lebegıpontos szám mantisszája a d-alapú számrendszerben általában olyan, hogy a szám bal szélsı jegye nem nulla, és a d-edespont vagy a szám bal szélén, vagy attól egy hellyel jobbra áll, tehát vagy egy egész jegyre, vagy az elsı törtjegyre normalizált. Korábban már említettük, hogy a fixpontos számokat a gép többnyire egészként kezeli, vagyis a fixpontos számok szorzásánál értékes jegyek vesznének el a szorzásnál, ha a szorzat hossza megegyezne a tényezık hosszával. Hogy ez a torzítás ne következzen be, ezért a gépek túlnyomó többségében van olyan szorzási utasítás, amelynek az eredménye kétszer olyan hosszú, mint a két operandus hossza, és így a szorzat a helyes eredményt adja. Ez a másik lehetıség arra, hogy a szorzásnál ne veszámokat n hosszon adjuk meg m törtjeggyel, akkor a relatív hiba legalább
DIGITÁLIS ARITMETIKA
66
szítsünk lényeges információt, ugyanakkor maximálisan ki tudjuk használni az operandusok számára rendelkezésre álló helyet (ha a szorzat az operandusokkal azonos hosszúságú, és az operandusok egészek, akkor korábban már láttuk, hogy az operandusok csak a lehetséges hossz felét foglalhatják el). Ezek után rátérünk az egyes ábrázolási módok vizsgálatára. Elıször is megjegyezzük, hogy az eltolt nullpontú számokat általában nem szorozzuk és osztjuk, hiszen ez az ábrázolási mód szinte kizárólag a lebegıpontos számok kitevıjénél fordul elı, és a kitevıket általában nem szorozzuk. Az is könnyen belátható, hogy elıjeles abszolút értékes számok szorzását úgy végezzük, mint az elıjel nélküli számok szorzását, figyelembe véve, hogy csak az abszolút értékeket kell szorozni, és az elıjel a két elıjelbıl az elıjelszabály segítségével közvetlenül megkapható. A komplemens kóddal ábrázolt számok szorzásához emlékeztetünk rá, hogy ((a mod v )(b mod v ) mod v ) = (ab mod v ) , ha a, b és v M M M M egyaránt egész szám (42. oldal). Ha a két szám N 1 és N 2 , akkor − , − , ≤ N1 < ≤ N2 < 2 2 2 2 továbbá ϕ k ( N 1 ) = s1 M + N 1 = ( N 1 mod M ) és ϕ k (N 2 ) = s 2 M + N 2 = ( N 2 mod M ) . Mivel mind ϕ k (N 1 ) , mind ϕ k ( N 2 ) , mind M egész szám, ezért alkalmazható az elıbb idézett szabály, vagyis
(ϕ k (N1 )ϕ k (N 2 ) mod M ) = = ((N 1 mod M )(N 2 mod M ) mod M ) = = (N 1 N 2 mod M ) = ϕ k (N 1 N 2 ) M M ≤ N1 N 2 < . 2 2 Az elıbbi eredmény azt jelenti, hogy ha a komplemens kóddal ábrázolt egész számok szorzata elfér a megadott eredeti hosszon, akkor a komplemens kódolású számok szorzatának a tényezık hosszával azonos hosszúságú komplemens kódja a kódok szorzatának modulo M maradéka. Mivel az elıbbi eredmény csak igen kis abszolút értékő operandusokat enged meg (legalábbis a lehetséges hosszhoz viszonyítva), ezért most is igaz, hogy általában van olyan szorzás, ahol az eredmény kétszeresen hosszon keletkezik. Kérdés, hogy most milyen kapcsolat van a tényezık kódja és az eredmény kódja között. Legyen t és v nullától különbözı valós szám, ekkor feltéve, hogy nincs túlcsordulás, azaz −
(( a
mod v )( b mod v ) mod tv ) =
( a mod v )( b mod v ) . = ( a mod v )( b mod v ) − tv tv
(b mod v ) < 1 , ezért 0 ≤ (a mod v )(b mod v ) < 1 . Ha tehát tv ≥ v 2 , akkor mod v ) < 1 és 0 ≤ v v v2 (a mod v )(b mod v ) = 0 , és ((a mod v )(b mod v ) mod tv ) = (a mod v )(b mod v ) . Az eredményt altv kalmazzuk a komplemens kódban megadott operandusokra. Ekkor az elıbbi eredmény a szorzat kétszeres hosszával 0≤
(a
ϕ k ( N 1 )ϕ k ( N 2 ) = (N 1 mod M )(N 2 mod M ) = = (s1 M + N 1 )(s 2 M + N 2 ) = s1 s 2 M 2 + (s1 N 2 + s 2 N 1 )M + N 1 N 2 = = (sM 2 + N 1 N 2 ) + ((s1 s 2 − s )M + (s1 N 2 + s 2 N 1 ))M =
,
= ϕ k (N 1 N 2 ) + ((s1 s 2 − s )M + (s1 N 2 + s 2 N 1 ))M
ahol s a szorzat elıjele. Most az operandusok kódjainak szorzata akkor és csak akkor azonos a szorzat kódjával ( M 2 -tel való maradékolás után), ha az utolsó sorban a második tag M egész számú többszö-
Számítógépi matematika
67
röse, azaz ha (s − s1 s 2 )M − (s1 N 2 + s 2 N 1 ) = kM egy egész k-val. A bal oldali elsı tag biztosan egész számú többszöröse M-nek, így a feltétel pontosan akkor teljesül, ha s1 N 2 + s 2 N 1 = lM egy l egésszel. M − M ≤ s1 N 2 + s 2 N 1 < , és ebben a tartományban M-nek két többszöröse van, a 0 és a − M . Az 2 elıbbi értéket akkor és csak akkor kapjuk, ha s1 és s 2 egyaránt 0, vagyis mindkét szám pozitív, vagy ha N1 és N 2 legalább egyike 0, mert ha például N 1 = 0 , akkor egyúttal s1 = 0 is teljesül. A másik eset pedig akkor és csak akkor jön létre, ha mindkét tényezı a maximális abszolút értékő negatív M . szám, azaz mindkettı − 2 A lényeg az, hogy ha a szorzat hossza kétszerese a tényezık hosszának, akkor a komplemens kódok szorzata általában nem egyenlı a tényezık kódja szorzatának a maradékával. A probléma megoldására három mód is kínálkozik:
• a tényezık komplemens kódjáról áttérünk az elıjeles abszolút értékes kódra, elvégezzük a szorzást, majd a kétszeres hosszúságú, elıjeles abszolút értékes kódú eredményt átkonvertáljuk a kétszeres hosszúságú komplemens kódra; • az egyszeres hosszúságú komplemens kódok kétszeres hosszúságú szorzatát korrigáljuk. A fentebb kapott eredménybıl
ϕ k ( N 1 N 2 ) = ϕ k ( N 1 )ϕ k ( N 2 ) − ((s1 s 2 − s )M + (s1 N 2 + s 2 N 1 ))M . ϕ k ( N i ) = s i M + N i -bıl N i = − s i M + ϕ k (N i ) , továbbá s = s1 ⊕ s 2 = s1 + s 2 − 2s1 s 2 , és így
(s1 s 2 − s )M + (s1 N 2 + s 2 N 1 ) = ((1 − s1 )(1 − s 2 ) − 1)M + (s1ϕ k (N 2 ) + s 2ϕ k (N 1 )) vagyis a korrekciós tag az operandusok kódjaiból kiszámítható; • szorzás elıtt mindkét tényezıt kiterjesztjük az eredeti hossz kétszeresére, és így végezzük a szorzást. Ekkor a szorzat hossza azonos a tényezık hosszával, és így a kódok szorzata közvetlenül a szorzat kódját adja. A második módszer nyilván nem túl célszerő, míg a harmadikkal az a probléma, hogy nagy a helyigénye, hiszen a szorzáshoz három darab dupla hosszúságú regiszter kell, míg majd látjuk, hogy maga a szorzás elvégezhetı a két eredeti operandust tartalmazó regiszter, valamint egy további, az eredeti hosszakkal azonos mérető regiszter segítségével, ezért leggyakrabban az elsı módszert alkalmazzák a gépekben. Ennek ellenére megnézzük a hosszkiterjesztést, mert ez egyébként is elıfordul az olyan gépekben, amelyekben az operandusok hossza nem csak egy érték lehet, hanem egy rögzített minimális érték néhány kis egész számú többszöröse. (A mai gépek szinte mindegyike ilyen, mint korábban már volt szó róla, nevezetesen a legkisebb hossz a bájt, és ennek kétszerese a félszó vagy szó, a négyszerese a szó vagy dupla szó, és elıfordul még a nyolcszoros hossz is, sıt akár tízszeres és a tizenhatszoros is.) Igen egyszerő az elıjeles abszolút értékes kódolásnál a hosszkiterjesztés. Ha az eredeti szám kódja
n1 −1
∑i =0 ai r i , és ur n
1
= M = 2 K , ahol r ≥ u ∈ N , továbbá u páros, akkor a kiterjesztett szám kód-
a n − 2 u n − 1 2 ja ∑i =0 a i r i + a n1 −1 mod r n1 −1 + ∑i = n 0 ⋅ r i + 1 r n2 −1 . u = 2 , tehát például bináris esetben ez 1 2 u 2 egyszerően azt jelenti, hogy a bal szélsı bitet írjuk a kiterjesztett kód bal szélsı pozíciójába, majd az eredeti bal szélsı pozícióba, és ettıl balra az új elıjelbitig, azt már nem beleértve, végig 0-t írunk. n1 − 2
DIGITÁLIS ARITMETIKA
68
A bináris komplemens kód esetén a hosszkiterjesztés az úgynevezett elıjel-kiterjesztéssel történik. Általános esetben a komplemens kódolásnál a szám eredeti kódja sur n1 −1 + N , míg az új kód
ϕ k(2 ) (N ) = sur n2 −1 + N = sur n2 −1 − sur n1−1 + ϕ k(1) ( N ) = = sur n2 −1 − sur n1−1 + an(11 −) 1r n1 −1 + N ′ =
(
)
= s(u − 1)r n2 −1 + s (r n2 −1 − r n1 ) + s (r − u ) + an(11−) 1 r n1−1 + N ′ = n2 − 2
= s(u − 1)r n2 −1 + ∑ s (r − 1)r i + an(12−)1r n1−1 + N ′ i = n1
an(12−)1 = s (r − u ) + an(11−) 1 az eredeti an(11−) 1 -gyel azonos, ha a N nem negatív, és (r − u ) + an(11−) 1 -gyel, amennyi-
u u ≤ an(11−) 1 < u ≤ r , ezért r − ≤ (r − u ) + an(11−) 1 < r , tehát 2 2 an(12−)1 < r , an(12−)1r n1−1 + N ′ is r-alapú számrendszerben felírt szám, amelyre an(12−)1r n1−1 + N ′ < r n1 , így ez a
ben az eredeti szám negatív. Az utóbbi esetben
n2 − 2
szám nem módosítja s(u − 1)r n2 −1 + ∑ s(r − 1)r i értékét. Ez viszont olyan szám, amelynek vagy minden i = n1
jegye 0, vagy a bal szélsı kivételével valamennyi r − 1 , és a bal szélsı jegy u − 1 . Bináris esetben ez azt jelenti, hogy an(12−)1 = an(11−) 1 = s , és a kiterjesztés valamennyi bitje azonos az elıjegybittel, s-sel, tehát egész egyszerően az elıjegybitet kell balra a szám elején minden pozícióba beírni, ami indokolja az elıjel-kiterjesztés elnevezést.
Az elıbbiek alapján elegendı megnézni, hogy hogyan történhet az egész számok abszolút értékének a szorzása. Valamivel általánosabban legyen N1 = ∑i =1 0 ai(1) r i és N 2 = ∑i =2 0 ai(2 ) r i , ton −1
n −1
vábbá legyen N 2 > T = ∑i = 0 t i r i ∈ N , és számítsuk ki N 1 N 2 + T -t. S (0 ) = r n1 T + N 1 -bıl indulva n2 −1
(
n + n −1
(
(
S (i +1) = r −1 S (i ) + S 0(i ) r n1 N 2
legyen S (i ) = ∑ j1= 0 2 S (ji ) r j és
)
)), ahol
n1 > i ∈ N . Tegyük fel, hogy
S (i ) = r n1 −i T + N 2 ∑ j =0 S 0( j ) r j + r − i N 1 . Ez i = 0 esetén igaz, és ha igaz egy n1 -nél kisebb nem i −1
negatív egész i-re, akkor i −1 S (i +1) = r −1 r n1 −i T + N 2 ∑ S 0( j ) r j + r −i N 1 + S 0(i ) r n1 N 2 j =0
(
) =
i = r n1 −(i +1) T + N 2 ∑ S 0( j ) r j + r −(i +1) N 1 j =0
(
)
( (
)
)
tehát igaz lesz i + 1 -re is. S 0(i ) = S (i ) mod r = r n1 −i T + N 2 ∑ j = 0 S 0( j ) r j + r − i N 1 mod r , és innen S 0(i ) = ( r − i N1 mod r ) =
(∑
n1 −1 j =i
)
i −1
(
)
a (j1)r j mod r = ai(1) , így S (i ) = r n1 −i T + N 2 ∑ j =0 a (j1) r j + r − i N 1 , és i −1
S (n1 ) = T + N 2 ∑ j1=0 a (j1) r j = N 1 N 2 + T , azaz a rekurzió az n1 -edik lépés után éppen a kiszámítandó n −1
értéket adja. Figyelembe véve, hogy az r-rel való osztás megfelel az r-edespont egy jeggyel balra való eltolásának, ami viszont azonos azzal, mint ha a rögzített r-edesponthoz képest a számot egy helyiértékkel jobbra toljuk, és az osztás utáni egészrész-képzés azt jelenti, hogy elhagyjuk az elıbbi jobbratolás után a jobb oldalon kilépı jegyet, a szorzást például a következı módon végezhetjük, amennyiben a szorzat hossza a két operandus hosszának az összege.
Számítógépi matematika
69
Helyezzük el N 1 -et egy n1 + n 2 hosszúságú regiszter jobb szélére igazítva, és a regiszter megmaradó bal oldali részébe írjuk be T-t, ekkor a regiszterben S (0 ) áll. Tegyük N 2 -t egy n2 helyiértékő regiszterbe, és helyezzük képzeletben ezt a regisztert az elızı regiszter alá úgy, hogy a bal szélük igazodjon, amint az alábbi 24. ábra mutatja. n1 T
N1
N2 n2
24. ábra
Ezek után végezzünk n1 lépést úgy, hogy mindegyik lépésben a felsı regiszter jobb szélsı jegyével szorozzuk meg a második regiszterben álló N 2 -t, és a szorzatot adjuk hozzá az n1 + n 2 hosszúságú regiszter felsı n2 pozícióján álló számhoz – ez megfelel annak, hogy az i-edik lépésben a i(1) N 2 r n1 -et adtunk az addig a hosszabb regiszterben álló számhoz – , majd toljuk el egy pozícióval jobbra az n1 + n 2 hosszúságú regisztert, és hagyjuk el a jobb szélen kilépı jegyet. Ha feltételezzük, hogy ezen lépés megkezdésekor ebben a regiszterben S (i ) állt, akkor látható, hogy az összeadás után már r −1 S (i ) + ai(1) N 2 r n1 = S (i+1) lesz a regiszterben. Az elıbbi lépést n1 -szer végrehajtva az utolsó lépés
(
)
(1)
során a n1 −1 lépett ki a jobb oldalon, vagyis N 1 -et teljesen kiléptettük, és a hosszabb regiszterben S (n1 ) található. Az eljáráshoz még annyit jegyzünk meg, hogy mivel egész számok abszolút értékérıl van szó, u ezért mindkét operandus esetében N < r n−1 . Amennyiben r = 2 , akkor u is 2, és az elıbbi egyenlıt2 lenség azt jelenti, hogy N kódjában a legmagasabb helyiértékő jegy, vagyis az, amely az n − 1 indexő pozíción áll, biztosan 0. Ez természetesen érthetı, hiszen bináris ábrázolás esetén ezen a pozíción végeredményben véve a szám elıjele áll, ami az abszolút érték esetén felesleges. A bináris eset azért is könnyő, mert most a regiszter jobb szélsı jegye – mint valamennyi jegy – csak 0 vagy 1 lehet, és az elıbbi esetben a léptetésen kívül nincs tennivalónk, míg a második esetben is elmarad a szorzás, csupán a második operandust hozzá kell adni az addigi részeredmény bal felsı részéhez a léptetés elıtt. Nézzük az elıbbieket két konkrét példán. Elsıként legyen r = 5 , u1 = 4 = u 2 , n1 = 4 , n 2 = 3 , N 1 = 1302 5 , N 2 = 143 5 és T = 32 5 . n1 = 4 , tehát négy lépést teszünk, mindegyikben elıbb egy egyjegyő számmal szorozva egy számot, majd egy összeadást és utána egy jobbra léptetést végezve. A kiinduló helyzet a következı: 0
3
2
1
4
3
1
3
0
2
A felsı regiszter jobb szélsı jegye 2, ezért 2 5 ⋅ 143 5 = 3415 -öt adunk a felsı regiszter bal szélén álló háromjegyő számhoz:
DIGITÁLIS ARITMETIKA
70
4
2
3
1
3
0
2
032+2×143 1
4
3
és egy hellyel jobbra léptetjük a regisztert. Ekkor balról 0 lép be, és jobb oldalon a kilépı jegy elvész: 0
4
2
1
4
3
3
1
3
0
Ezzel vége az elsı lépésnek. Most a felsı regiszter jobb szélsı jegye 0, ezért a szorzás után nem változik a regiszter tartalma: 0
4
2
1
4
3
0
0
4
1
4
3
3
1
3
0
2
3
1 3
majd egy hellyel jobbra léptetünk:
és kész a második lépés is. A regiszter jobb szélsı jegye 3, így 4-hez 35 ⋅ 143 5 = 1034 5 -at adunk, és ekkor a regiszter tartalma 1
0
4
3
2
3
1
3
004+3×143 1
4
3
és látható, hogy egy átviteljegy keletkezett. Ismét jobbra léptetünk egy jeggyel: 1
0
4
1
4
3
3
2
3
1
Számítógépi matematika
71
és mint látjuk, az átviteljegy „eltőnt”, belépett a regiszterbe. Végül jön a negyedik lépés. A legalacsonyabb helyiértéken álló jegy 1, így végeredményben véve egyszerően hozzá kell adni az alsó regiszter tartalmát a felsı regiszter bal szélsı három jegyébıl álló számhoz: 3
0
2
3
2
3 1
104+1×143 1
4
3
és az egy hellyel való jobbraléptetés után megkapjuk a végeredményt: 0
3
0
2
3
2
3
1
4
3
1 3
4
3
× 1
3
0
2
4
1
Valóban:
1
0
3 4
1
4
3
3
0
2 2
4
1
0
3
2
2 3
2
3
+ 3
0
vagyis 032 5 + 1302 5 ⋅ 143 5 = 0302323 5 . A harmadik lépés során az összeadás után szükség volt egy átviteljegyre. Ilyen eset nem foru u 2 dulhat elı, ha u 2 = 2 , hiszen N 2 < 2 r n2 −1 , így a n(22 )−1 < 2 = = 1 , és mivel a n(22 )−1 nem negatív egész 2 2 2 (2 ) szám, ezért a n2 −1 = 0 . Már többször említettük, hogy bináris és ternáris számrendszer használata esetén elıjeles számoknál u értéke nem is lehet más, mint 2, és ez azt jelenti, hogy a kettes illetve a hármas számrendszerben felírt elıjeles számok szorzásánál az átviteljegy helyén nem keletkezhet nullánál nagyobb érték. A második példában r = 2 , így u1 = 2 = u 2 , n1 = 4 , n 2 = 3 , N 1 = 0101 2 , N 2 = 010 2 , és T = 12 . Most az elıbbinél tömörebben adjuk meg a számítás menetét (alább a 25. ábra). Valóban a helyes eredményt kaptuk, hiszen a két operandus 5 és 2, és a végeredmény helyén éppen 1 + 5 ⋅ 2 = 11 bináris felírása áll (most mindhárom számot a tízes számrendszerben írtuk).
(
(
Az ismertetett rekurzióban S ( j +1) = r −1 S ( j ) + a (j1) r n1 N 2
(
)
(
)
)) , vagyis egy összeadáson kívül ki
kell számítani a (j1) r n1 N 2 = r n1 a (j1) N 2 -t. Itt r n1 csupán annyit jelent, hogy a (j1) N 2 -t a részeredményt tároló regiszter felsı n2 jegyébıl álló számhoz adjuk hozzá, tehát valójában arról van szó, hogy ki kell számolni N 2 -nek és a (j1) -nek, azaz egy (általában) többjegyő és egy egyjegyő számnak a szorzatát. Ez azt jelenti, hogy két többjegyő szám szorzásának kérdését visszavezettük összeadásra, és egyjegyőnek többjegyővel való szorzására. Abban a speciális esetben, amikor az alkalmazott számrendszer alap-
DIGITÁLIS ARITMETIKA
72
száma 2, akkor az egyjegyő szám 1, és ekkor a szorzás elmarad, tehát ebben a speciális esetben csupán összeadás (és léptetés) segítségével végezhetı a szorzás, minden más esetben azonban szükség van egyjegyőnek többjegyővel való szorzására. A kérdés nem csupán teoretikus, hiszen a számítógépben szükség van a BCD-alakban ábrázolt számok szorzására is. Nézzük meg ezért, hogy hogyan történik egy egyjegyő számnak egy (akár) többjegyő számmal való szorzása. N1 0
0
1
0 1
0
1
Léptetés
0
1
1
0 1
0
1
0
0
1
1 0
1
0
Léptetés
0
0
1
1 0
1
0
0
0
0
1 1
0
1
0
1
0
1 1
0
1
0
0
1
0 1
1
0
0 Léptetés Végeredmény 0
0
1
0 1
1
0
0
0
1 0
1
1
0
1
0
Összeadás
Összeadás Léptetés
N2 25. ábra
Mivel most csak az az érdekes, hogy hogyan szorzunk egy egyjegyő számot egy többjegyő n −1
számmal, ezért legyen N = ∑i =0 ai r i , és b az egyjegyő szám. Azt azért vegyük figyelembe, hogy a n −1
szorzatot egy korábban már kiszámolt értékhez kell hozzáadni. Legyen ez az érték T = ∑i =0 t i r i az ralapú számrendszerben. Mind b, mind a i , mind t i az r-alapú számrendszer egy-egy jegye, ezért r > b ∈ N , r > a i ∈ N és r > ti ∈ N , vagyis r − 1 ≥ b ∈ N , r − 1 ≥ a i ∈ N , és r − 1 ≥ t i ∈ N . Ekkor
(r − 1)2 ≥ bai ∈ N , és (r − 1)2 < r 2 , tehát a két egyjegyő szorzata legfeljebb kétjegyő lesz (ez egyébként a korábbi eredményekbıl is világos). Ha r > 2 (és mostani vizsgálatukban csak ennek van értelme), akkor (r − 1)2 = r 2 − 2r + 1 = (r − 2 ) r + 1 , így elıfordul, hogy a két egyjegyő szorzata kétjegyő. Ugyanakkor
(r − 1)2 + 2(r − 1) = r 2 − 1 < r 2 ,
ami azt jelenti, hogy ha valamilyen n 2 > i ∈ N -re
2
r > c i −1 ∈ N , akkor r > t i + bai + ci −1 ∈ N , tehát t i + ba i + c i −1 = mi + ci r , ahol m i az r-alapú számrendszer tetszıleges jegye lehet, és c i -re is teljesül, hogy r > c i ∈ N . Ha megadjuk c −1 értékét, akkor már meghatároztuk minden n 2 > i ∈ N -ra m i és c i értékét. Ekkor n −1
n −1
i =0
i=0
n −1
T + bN + c −1 = ∑ t i r i + b∑ a i r i + c −1 = ∑ (t i + ba i ) r i + c −1 = n −1
i =0 n −1
n
= ∑ ((mi − ci −1 ) + c i r ) r i + c −1 = ∑ (mi − c i −1 ) r i + ∑ c i −1 r i + c −1 = i =0
i =0
i =1
n −1
n
i =0
i =0
= m0 + ∑ (mi − c i −1 + ci −1 ) r i + c n −1 r n = ∑ mi r i
Számítógépi matematika
73
ahol m n = c n −1 . (A most kapott eredmény n + 1 -jegyő, vagyis az eredeti esetben n 2 + 1 -hosszúságú, ám ennek a szorzatnak a korábbi eredményhez való hozzáadása után az eredményt egy pozícióval jobbra léptetjük, ezért helyes volt a feltételezésünk, hogy T is csak n-jegyő.) A most kapott eredmények pontosan azok, ahogy papíron és ceruzával elvégezzük a szorzást. Két többjegyő számot ugyanis úgy szoktunk összeszorozni, hogy a szorzandót egymás után megszorozzuk a szorzó egyes számjegyeivel, mondjuk a számjegyekben jobbról balra haladva, vagyis egy többjegyő számot megszorzunk egy egyjegyővel, majd az így kapott részeredményeket mindig egyegy pozícióval balra helyezve, egymás alá írjuk, és végül összeadjuk ıket. Ehhez képest nem jelent lényeges változást, ha az összeadást nem a végén végezzük el, hanem valahányszor végeztünk egy részszorzással, a szorzatot rögtön hozzáadjuk az addigi részösszeghez, és az sem jelent lényeges eltérést, ha nem az éppen kiszámított részszorzatot írjuk az addigi összeghez képest egy jeggyel balra, hanem az összeget egy pozícióval jobbra. Az egyjegyőnek többjegyővel való szorzását pedig úgy végezzük a kézi számolásnál, hogy jobbról balra haladva megszorozzuk a többjegyő szám soron következı jegyét az egyjegyővel, ehhez hozzáadjuk az elızı szorzásból származó átvitelt, majd leírjuk az így kapott legfeljebb kétjegyő szám alacsonyabb helyiértékő jegyét mint a szorzat aktuális jegyét, és a magasabb helyiértékő jegy lesz a következı szorzásnál az elızı pozícióról való átvitel. De ha megnézzük, pontosan ezt csináltuk a fentebb felírt eljárásban is. Most már nincs is más feladatunk, mint meghatározni két egyjegyő szám szorzatát. Ezt megtehetjük például ismételt összeadással, de úgy is, hogy egy r × r -es táblázatban megadjuk minden r > a ∈ N , r > b ∈ N értékhez a megfelelı (u, v ) párt, ahol r > u ∈ N , r > v ∈ N , és ab = u + vr .
egész_szorzás_kétszeres_hosszon R (a ) = A R(f ) = T ciklus i = 0 -tól n1 − 1 -ig t = R(0 ) w=0 ciklus j = 0 -tól n2 − 1 -ig
s = R ( f ) ( j ) + u (t , B ( j )) + w
s w= r (f ) R ( j ) = s − rw w = v(t , B( j )) + w ciklus vége C=w R => C R ciklus vége eljárás vége. 3. algoritmus
Végezetül nézzük a szorzás algoritmusát az elızıek alapján (3. algoritmus). Az elsı, n1 hoszszúságú operandus az A, míg a másik, n2 hosszúságú operandus a B tömbben van, és a szorzathoz adandó érték a szintén n2 hosszúságú T tömbben. Az eredmény az R tömbben keletkezik, amelynek az n1 alacsonyabb helyiértékő jegyeibıl álló részt R (a ) , a felsı n2 jegybıl álló részét R ( f ) jelöli. Az r-alapú számrendszer jegyeinek szorzatát az u illetve v tömb tárolja, az elıbbiben az alacsonyabb, az utóbbiban a magasabb helyiértékő jeggyel. Az esetleges átviteljegyet C-ben tároljuk.
DIGITÁLIS ARITMETIKA
74
Az algoritmusban C R a C-ben álló jegy és R konkatenációját, azaz egymás mellé írását, összefőzését jelent, és > az utána álló érték egy pozícióval való jobbra léptetése, a jobb oldalon kilépı jegy elhagyásával. A fentiekben tulajdonképpen elintéztük a BCD-számok szorzását is, és a lebegıpontos számokét is. Ha ugyanis α 1 = m1 d k1 , és α 2 = m2 d k 2 , akkor α 1α 2 = (m1 m2 )d k1 + k 2 , vagyis a lebegıpontos számok szorzása úgy történik, hogy összeszorozzuk a mantisszákat, és összeadjuk a kitevıket (majd a végén esetleg normalizálunk). De a gépben mind a mantissza, mind a kitevı fixpontos alakban van, és az ilyen alakokat már tudjuk összeadni is, és szorozni is. Még az osztás van hátra. Itt azt kell figyelembe venni, hogy mindkét operandus véges sok jeggyel megadott szám, ám már tudjuk, hogy két ilyen szám hányadosa igen gyakran csak végtelen sok jeggyel adható meg. Egész számok esetén van azonban az osztásnak egy másik fajtája is, a maradékos osztás, amely minden esetben véges hosszon pontos eredményt ad (kivéve, ha nullával szeretnénk osztani). A számítógépekben általában a lebegıpontos számok mantisszáinak osztása a közönséges osztással, míg a fixpontos, valamint a BCD számoké – mivel ezeket a gép általában egész számnak tekinti – maradékos osztással történik. Mivel a fixpontos számok szorzásánál a szorzatot leggyakrabban kétszeres hosszon adjuk meg, ezért azt az esetet nézzük meg, amikor egy kétszeres hosszúságú operandust osztunk egy egyszeres hosszúságú operandussal. Valamivel általánosabban tegyük fel, hogy a szorzásnál n1 és n2 jeggyel megadott, egész számként kezelt operandusokat szorzunk, és az eredmény n1 + n 2 hosszúságon keletkezik, és nézzük meg a maradékos osztást. Legyen v1 és v2 az r-nél kisebb nem negatív egész szám, az osztandó N, az osztó N 2 , N = N 1 N 2 + M , és M < N 2 < v 2 r n2 − 2 . Az osztás csak akkor végezhetı el túlcsordulás nélkül, ha tel-
(
)
jesül az N 1 < v1 r n1 −1 feltétel, amihez szükséges az N ≤ v1 r n1 −1 − 1 N 2 + (N 2 − 1) = v1 r n1 −1 N 2 − 1 össze-
(
)
függés, és ebbıl rN < v1 r n1 N 2 . Ha visszaemlékszünk a szorzásra, akkor ott az történt, hogy az n1 + n 2 hosszúságú regiszter jobb szélsı jegyével megszoroztuk r n1 N 2 -t, a szorzatot hozzáadtuk az elıbbi regiszter tartalmához, majd az egész regisztert elléptettük egy pozícióval jobbra, miközben a bal szélen belépett az esetleges átviteljegy, és a jobb szélen kilépett a legalacsonyabb helyiértéken álló jegy. Ha tehát N-et behelyezzük az n1 + n 2 -jegyő regiszterbe, majd ezt egy pozícióval balra léptetjük, miközben a jobb oldalon egy 0-t léptetünk a regiszterbe, akkor a regiszterben rN lesz. A hosszú regiszterben lévı számnak r n1 N 2 -vel való osztását például úgy tudjuk elvégezni, hogy a regiszter felsı n2 jegyébıl álló számból ismételten levonjuk N 2 -t mindaddig, amíg a maradék nem negatív, és a hányados a kivonások száma lesz. Az oszthatósághoz a korábbiak szerint az szükséges, hogy ez a hányados kisebb legyen v1 -nél (és mivel bináris esetben v1 biztosan 1, ezért bináris osztáskor ez a legelsı hányados szükségszerően 0). Ha az osztás nem végezhetı el, mert ez a hányados legalább v1 , akkor megállhatunk, és jelezzük a túlcsordulást. Ellenkezı esetben a kapott hányados lesz N 1 legmagasabb helyiértékő jegye, ami szorzáskor a regiszter jobb szélsı jegye volt, vagyis most az a teendınk, hogy ezt a jegyet beírjuk az osztandót tartalmazó regiszter jobb szélsı pozíciójába. Innen kezdve az elıbbi procedúra ismétlıdik azzal az eltéréssel, hogy a hányados már akár r − 1 is lehet, összesen (az elıbbi lépéssel együtt) n1 -szer, vagyis léptetünk és osztunk, és az utolsó lépés után a hosszú regiszter alsó n1 pozícióján kapjuk a hányadost, míg a felsı n2 jegy tartalmazza a maradékot. Az elıbbiekben mind az osztó pozitív, míg az osztandó nem negatív volt. Ha akár az osztó, akár az osztandó negatív, akkor elsı lépésként az elıbbi eljárást az abszolút értékekkel végezzük. Ha az osztandó negatív, akkor az elıbbi hányados és maradék helyett azok ellentettjét kell venni. Amenynyiben a maradék nem nulla, akkor most negatív lesz, amit úgy korrigálunk, hogy hozzáadjuk az osztó abszolút értékét. Végül, ha az osztó negatív, akkor még vesszük a hányados ellentettjét. Ekkor a maradék biztosan nem negatív lesz, míg a hányados pontosan akkor lesz negatív, ha az osztandó és az osztó ellenkezı elıjelő.
Számítógépi matematika
75
Az osztáshoz külön példát nem adunk, ugyanis egyszerően a szorzás példáit kell fordított sorrendben végrehajtani. A lebegıpontos számok osztása a szorzásnál mondottak értelemszerő alkalmazásával egyszerő, így azt külön nem tárgyaljuk.
77
LOGIKAI ALGEBRA Ebben a részben azt a kérdést vizsgáljuk, hogy az elıbbiekben megfogalmazott aritmetikai mőveletek milyen módon valósulnak meg a számítógépben. Láttuk, hogy valamennyi mővelet elıáll az egy helyiértékkel balra vagy jobbra való léptetéssel, komplementálással, valamint két n-bites bináris szám összeadásával, így ha ezeket a feladatokat alkalmas mőszaki berendezések elvégzik, akkor megvalósítottuk a gép aritmetikai egységét. Éppen a mőszaki szempont volt az egyik oka, hogy a számítógép mőködését a kettes számrendszerre alapoztuk, így a realizáláshoz azt a kérdést kell vizsgálni, hogy milyen n-változós leképezések léteznek, ha valamennyi változó és a függvény értéke is csupán két értéket, mondjuk a 0-t és az 1-et veheti fel. Az ilyen függvényeket Boole-függvénynek mondjuk. Lássuk kissé közelebbrıl ıket. Elsıként megállapítjuk, hogy ha n természetes szám, akkor az n-változós Boole-függvények n száma 2 2 . Rögzítsük ugyanis a változók sorrendjét. Ekkor a változók valamely konkrét értékét egy nullákból és egyekbıl álló n-hosszúságú sorozat adja meg, és ez fordítva is igaz, azaz bármely elıbbi sorozat a bemenı változók egy lehetséges értéke, továbbá különbözı sorozat különbözı bemenetet, míg eltérı bemenet más és más sorozatot ad, így a bemeneti értékek lehetséges száma megegyezik az n-hosszúságú 0 - 1 sorozatok számával. Egy ilyen sorozat viszont felfogható egy n-jegyő bináris egésznek, és ezek szám 2 n . Ha most a bemeneteket is sorba rendezzük például az elıbbi bináris szám alapján, akkor a függvényt egy 2 n hosszúságú bináris sorozattal írhatjuk le, és ismét igaz, hogy minden ilyen sorozathoz és csak ezen sorozatokhoz tartozik egy és csak egy függvény, és különbözı sorozat különbözı függvényt képvisel, ezért az elıbbi okoskodás alapján a függvények száma a 2 n -jegyő bináris számok számával esik egybe. 0
2 2 = 21 = 2 , így a nullaváltozós függvények száma 2. Ez a két függvény a két konstansfüggvény, az azonosan 0, illetve az azonosan 1 függvény, jelöljük ıket az elıbbi sorrendben f 0(0 ) -val
illetve f 1(0 ) -val. Általában, ha a változók sorrendjét rögzítettük, akkor az n-változós fügvények és a n
2 2 > k ∈ N számok kölcsönösen megfeleltethetıek egymásnak, ezért a k-nak megfeleltetett nváltozós függvényt f k(n ) -val jelölhetjük. 1
2 2 = 2 2 = 4 , az egyváltozós függvények száma 4. Vegyük sorra ıket (26. ábra). x0
0 1
f 0(1) f 1(1) f 2(1) f 3(1) 0 1 0 1 0 0 1 1 26. ábra
f 2(1) megismétli a független változó értékét, azaz az identikus leképezést valósítja meg, f 2(1) ( x 0 ) ≡ x 0 , ahol a hármas egyenlıségjel most az azonosságot jelenti. f 2(1) láthatóan ellentettjére változtatja a bemenet értékét, ez az ellentett-képzés vagy negálás, és ezt mint egyváltozós mőveletet a felülvonással jelöljük, tehát tetszıleges a értékre (most a tetszıleges azt jelenti, hogy a 0 vagy 1 lehet) f 2(1) (a ) = a (más jelölés például ¬ a ), így gyakran f 2(1) helyett is x0 -t vagy még egyszerőbben x -t írunk. Látjuk, hogy (a ) = a , 0 = 1 és 1 = 0 . Maradt még két függvényünk, f 0(1) és f 3(1) . Ezek azonban már ismerısek: az elıbbi a bemenettıl függetlenül 0-t ad, tehát ez az azonosan nulla függvény, míg a másik a konstans 1 függvény. Azt látjuk, hogy az 1-változós függvények egy része nem valódi 1-változós, hiszen ténylegesen nem függ a kimenet értéke a bemenettıl. Általában: ha az n-változós f függvényben az xi változó olyan, hogy a többi változó bármely rögzített értéke esetén mind xi = 0 ,
LOGIKAI ALGEBRA
78
mind xi = 1 mellett ugyanazt a függvényértéket kapjuk, akkor a függvény valójában független xi -tıl. Az ilyen változó neve fiktív változó, az ellenkezı esetben pedig lényeges változó. Nyilván igaz, hogy egy függvény bármely fiktív változója elhagyható, és viszont, mindig növelhetjük a változók számát fiktív változó bevezetésével. Most viszont felmerülhet a kérdés, hogy akkor valójában hány valódi n-változós függvény van, azaz olyan, amely valamennyi változójától n lényegesen függ. Jelöljük V n -nel az n-változós függvények számát, ekkor Vn = 2 2 , és legyen Wn a n n n Vk és Vn = ∑k =0 Wk . A két k k állítás közül a másodikat bizonyítjuk. Minden n-változós függvény legfeljebb n változótól függhet lényegesen, és nyilván mindegyik függvény esetén egyértelmő, hogy melyek ezek a változók. Az n n változó közül a k lényeges változó -féle módon választható ki, és persze más kiválasztással másik k függvényt kapunk. Egyfajta kiválasztással Wk különbözı függvény létezik, így az n-változós függvé-
valódi n-változós függvények száma, ekkor Wn = ∑k = 0 (− 1) n
n−k
n nyek közötti valódi k-változós függvények száma éppen W k . Ha minden k-ra vesszük ezeket az k értékeket, és ezeket összeadjuk, akkor minden n-változós függvényt pontosan egyszer számba vettünk. Az ellenkezı irány bizonyítását mellızzük, azt meghagyjuk házi feladatnak. Mindenesetre az imént kapott eredményt is fel lehet használni az ellenkezı irányú állítás bizonyításához.
2 Térjünk rá a kétváltozós függvényekre. Ezek száma 16, a valódiaké 10, és van W0 = 2 0 2 nullaváltozós és W1 = 4 egyváltozós. A 16 kétváltozós függvény: 1 x1 x0 f 0(2 ) f 1(2 ) f 2(2 ) f 3(2 ) f 4(2 ) f 5(2 ) f 6(2 ) f 7(2 ) f 8(2 ) f 9(2 ) f 10(2 ) f 11(2 ) f 12(2 ) f 13(2 ) f 14(2 ) f 15(2 )
00 01 10 11
0 0 0 0
1 0 0 0
0 1 0 0
1 1 0 0
0 0 1 0
1 0 1 0
0 1 1 0
1 1 1 0
0 0 0 1
1 0 0 1
0 1 0 1
1 1 0 1
0 0 1 1
1 0 1 1
0 1 1 1
1 1 1 1
A két szélsı oszlopban lévı függvény láthatóan a konstans 0 és konstans 1 függvény; f 10 ≡ x 0 , f12(2 ) ≡ x1 , f 5(2 ) ≡ x 0 és f 3(2 ) ≡ x1 az egyváltozósak, a maradék tíz a ténylegesen kétváltozós függvény. (2 )
Nézzük meg az egyes függvények tulajdonságait:
f 8(2 ) : ezt a függvényt mint kétváltozós mőveletet x1 ⋅ x 0 -val jelöljük, vagy a pontot egyszerően elhagyjuk (sok egyéb jelölés mellett, például x1 ∧ x 0 ), és logikai szorzásnak mondjuk (ismét számtalan egyéb elnevezés mellett, amelyek közül a legfontosabb a logikai és vagy csak és illetve konjunkció). Látjuk, hogy tetszıleges a, b és c {0, 1}-beli elemmel ab = ba , a mővelet kommutatív, (ab )c = a(bc ) , tehát asszociatív, aa = a , azaz idempotens, továbbá a ⋅ 0 = 0 , a ⋅ 1 = a , így a 0 zéruselem, 1 egységelem a mőveletre. Végül igaz az aa = 0 egyenlıség is.
f 14(2 ) : mőveleti jele +, és logikai összeadásnak nevezzük, egyéb jelölése ∨, és elnevezése logikai vagy, vagy és diszjunkció. Ismét kommutatív, asszociatív és idempotens, a + 0 = a , a + 1 = 1 , így az összeadásra nézve 0 az egységelem és 1 a zéruselem, és a + a = 1 . A szorzást és összeadást több lényeges kapcsolat köti össze: a (b + c ) = ab + ac , a + bc = (a + b )(a + c ) , vagyis mindkét mőve-
Számítógépi matematika
79
let disztributív a másik fölött, a(a + b ) = a és a + ab = a , ami a két elnyelési tulajdonság, végül a + b = a ⋅ b és a ⋅ b = a + b a deMorgan azonosságok (az elıbbiekben precedenciát is definiáltunk: a
szorzás elsıbbséget élvez az összeadással szemben). Ennek alapján a + b = ab és a ⋅ b = a + b . Mivel a szorzás és összeadás asszociatív, ezért könnyen kiterjeszthetıek kettınél több változóra is: ha u1 , K , u k mindegyike 0 vagy 1, ahol 3 ≤ k ∈ N + , akkor ezek összegét vagy szorzatát bármilyen sorrendben számolva azonos eredményre jutunk, így van értelme az u1 ⋅K ⋅ u k és u1 + K + u k kifejezésnek. Indukcióval könnyen belátható, hogy a deMorgan azonosságok akárhány változó esetén is érvényben maradnak, azaz szorzat negáltja a tagok negáltjainak összege, illetve összeg negáltja a tagok ellentettjeinek szorzata (Boole-algebrában a szorzásnak is tagja van).
f 6(2 ) : jele ⊕, neve modulo 2 összeg; más lényeges elnevezés a kizáró vagy. Ellenırizhetı a kommutativitás és asszociativitás, továbbá a ⊕ 0 = a , a ⊕ 1 = a , a ⊕ a = 0 és a ⊕ a = 1 . Eszerint 0 egységelem, és minden elemnek van inverze, önmaga. A szorzást ismét erısebbnek tekintve kevés számolással belátható, hogy a (b ⊕ c ) = ab ⊕ ac , vagyis a szorzás disztributív a modulo 2 összegre nézve. Az asszociativitás következtében ismét értelmes akárhány komponensre a mővelet, és így ez a függvény kiterjeszthetı n változóra. A c ⊕ c 0 x 0 ⊕ K ⊕ c n −1 x n −1 alakú n-változós kifejezést, és csak ezt, lineárisnak nevezzük (sokszor affinnak, és speciális esetként c = 0 -nál lineárisnak), ahol c és a c i -k értéke – egymástól függetlenül – 0 vagy 1. A lineáris függvények a változók speciális polinomjai. További egyszerő tulajdonságai a kizáró vagy mőveletnek a ⊕ b = 1 ⊕ a ⊕ b , a + b = a ⊕ b ⊕ ab , illetve a ⊕ b = ab + ab . f 9(2 ) : jelöljük o -rel. Ez is kommutatív és asszociatív, a o 0 = a és a o 1 = a , a o a = 1 és a o a = 0 , tehát most 1 egységelem, és a inverze ismét önmaga. A két utóbbi összefüggés azt fejezi ki, hogy a függvény értéke pontosan akkor 1, amikor a két változó értéke megegyezik, ezért érthetı, hogy ebben az esetben a függvény az ekvivalencia, és ilyenkor használjuk a szokásos a ≡ b és a ↔ b jelölést is, ám az asszociativitásból adódó, több változóra való kiterjesztés után kettınél több változóra ez a jelentése a függvénynek elvész, ezért alkalmaztunk más jelölést. Ha az összeadás erısebb precedenciájú, akkor a + (b o c ) = a + b o a + c , a o b = 0 o a o b , és a o b = a ⊕ b , a o b o c = a ⊕ b ⊕ c , és általánosítva u1 o K u n = u1 ⊕ ... ⊕ u n illetve u1 o K u n = u1 ⊕ ... ⊕ u n , attól függıen, hogy n páros vagy páratlan.
f 7(2 ) : neve Sheffer-vonás, NAND, NEM-ÉS és a b -vel jelöljük. Láthatóan ez a szorzás ne-
gáltja: a b = ab . Kommutatív, de nem asszociatív: (0 0) 1 = 0 ≠ 1 = 0 (0 1) , ezért több argumentum esetén szükséges a zárójelezés. a 0 = 1 , a 1 = a , a a = a , és (a b )(a b ) = ab , (a a )(b b ) = a + b .
f 1(2 ) : Pierce-vonás, NOR, illetve NEM-VAGY, és a jelölése ||. Látszik, hogy a b = a + b . Az elızıhöz hasonlóan ez a mővelet is kommutatív és nem asszociatív, továbbá a 0 = a , a 1 = 0 ,
a a = a , (a b ) (a b ) = a + b , (a a ) (b b ) = ab . f 11(2 ) : ez mint mővelet nem kommutatív, ezért lényeges megadni az argumentumok sorrendjét
is. f 11(2 ) (a, b ) = a → b , a neve a elıtagú implikáció, és b az utótag. A kommutativitást a fontos
a → b = b → a összefüggés helyettesíti. Nem is asszociatív, de a → (b → c ) = ab → c , ahol ismét a szorzás a magasabb precedenciájú, végül a → b = a + b . Lényeges tulajdonsága, hogy a ha ... akkor típusú szerkezetet írja le. Amennyiben az elıtag értéke 0, akkor a mővelet eredménye független az utótag értékétıl, míg ellenkezı esetben az utótag és az eredmény egybeesik.
LOGIKAI ALGEBRA
80
f 13(2 ) : ez az elızı függvény x0 és x1 felcserélésével, azaz a b elıtagú implikáció. f 4(2 ) és f 2(2 ) az elıbbi két függvény negáltjai, f 2(2 ) (a, b ) az a elıtagú inhibíció. Nyilván ez sem kommutatív, és nem is asszociatív. Most egy fontos összefüggést bizonyítunk. Legyen f n-változós Boole-függvény, ekkor
f ( x n −1 , K , xi +1 , xi , xi −1 , K , x 0 ) =
= x i f ( x n −1 , K , xi +1 , 0, xi −1 , K , x 0 ) + xi f (x n −1 , K , xi +1 ,1, xi −1 , K , x 0 ) ahol n > i ∈ N . Két függvény ugyanis pontosan akkor egyenlı, ha azonos argumentumokhoz azonos függvényérték tartozik. Most legyen u n −1 , K , u i +1 , u i −1 , K , u 0 – egymástól függetlenül – 0 vagy 1. Ha u i értéke 0, akkor a bal oldalon f (u n −1 , K , u i +1 , 0, u i −1 , K , u 0 ) áll, és a jobb oldal is ezzel az értékkel azonos, hiszen f (u n −1 , K , u i +1 , 0, u i −1 , K , u 0 ) szorzója 1, f (u n −1 , K , u i +1 , 1, u i −1 , K , u 0 ) -é viszont 0, és u i = 1 esetén is azonos a két oldal, mert most a jobb oldalon az elsı tagban szerepel a 0 szorzóként, a második tagban viszont a szorzó 1. Innen tovább folytathatjuk az eljárást: f mindkét kifejezésébıl kiemelhetjük mondjuk x j -t, ahol j ≠ i , és így négy tagot kapunk, majd ismét egyet és így tovább. Végül az alábbi kifejezésre jutunk: n −1 f ( x n −1 , K , x 0 ) = f ( u ,..., u ) ∑ n n−1 0 ∏ xiui i =0 (u0 ,...,u n −1 )∈{0,1}
n
2 −1 = ∑ α i mi(n ) i =0
(
n −1
n −1
k =0
k =0
)
ahol x 0 = x és x 1 = x , valamint mi(n ) = ∏ x kuk és α i = f (u n −1 , K , u 0 ) az i = ∑ u k 2 k indexszel. A fenti összefüggés azt a rendkívül fontos dolgot fejezi ki, hogy bármely Boole-fügvény felírható a logikai és, logikai vagy és negálás segítségével. Jóllehet ugyanazt a Boole-függvényt több különbözı logikai kifejezéssel is megadhatjuk, például x 0 + x1 és x0 ⊕ x1 ⊕ x 0 x1 mint kifejezések szemmel láthatóan nem azonosak, de bármit helyettesítve x0 és x1 helyére, a két kifejezés értéke azonos, az f ( x n −1 , K , x 0 ) =
2 n −1
∑ (α i mi(n ) ) felírás egyéri =0
telmő, vagyis ha f ( x n −1 , K , x 0 ) =
2 n −1
∑ (β i mi(n ) ) is igaz, akkor valamennyi i indexre
α i = β i . Legyen
i =0
ugyanis minden n > i ∈ N indexre x i = u i ∈ {0,1} . Mivel 0 0 = 0 = 1 = 11 , és 01 = 0 = 1 = 10 , ezért u t n −1
akkor és csak akkor 1, ha u = t . Ebbıl arra jutunk, hogy mi(n ) = ∏ x kuk pontosan akkor 1, ha minden k =0
2 n −1
(
)
k-ra x k -t u k -val helyettesítjük, vagyis f (u n −1 , K , u 0 ) = ∑ α i mi(n ) (u n−1 , K , u 0 ) = α s , ha i =0
n −1
∑ uk 2k = s , k =0
az α értékeket a függvény minden i együtthatóra egyértelmően meghatározza (ebben persze semmi újdonság nincs, hiszen az α-kat éppen az adott függvényértékek rövid jelöléseként vezettük be). (n ) (n )
(n )
Az mi -ek egyszerő tulajdonsága, hogy mi mi
(n )
= δ i , j mi
2 n −1
és
∑ mi(n ) = 1 , ahol δ i, j = 1 , ha i =0
(n )
i = j , egyébként δ i , j = 0 . mi mint n-változós függvény olyan, hogy a bemeneti jelek egyetlen kombinációjára 1 az értéke, egyébként 0, vagyis eltekintve az azonosan 0 függvénytıl, a lehetı legkevesebb 1-es található a táblázatos megadásában, két különbözı indexre ez az 1 a táblázat különbözı so-
Számítógépi matematika
81
rában áll, és így valamennyi ilyen függvény együttesen kiadja azt a táblázatot, amelyben csupa 1 áll, vagyis a konstans 1 függvényt. Mivel a szorzás kifejezhetı az összeadással és negálással, ezért ezek is elegendıek a függvények leírásához, és hasonló igaz, ha csak a szorzást és negálást tekintjük. Ha most például az összeadást és negálást tekintjük, akkor ezek egyike sem hagyható már el: egy egyváltozós függvényt akárhányszoros mélységben is alkalmazzuk, az továbbra is csak egyváltozós marad, ugyanakkor az összeadás értéke biztosan 1, ha legalább az egyik változó értéke 1, ezért ezzel a mővelettel 0-ból semmiképpen nem tudunk 1-et létrehozni. Figyelemreméltó azonban, hogy mind a Sheffer-vonás, mind a Pierce-vonás önmagában elegendı tetszıleges Boole-függvény kiváltására, hiszen ezekkel a negálás, a szorzás és az összeadás egyaránt megadható. A fenti ismeretek birtokában nézzük meg, hogy hogyan lehet elıállítani az N1 = ∑i =0 a i(1) 2 i n −1
és N 2 = ∑i =0 a i(2 ) 2 i bináris szám N1 + N 2 = ∑i =0 s i 2 i összegének számjegyeit (figyelembe véve, n −1
n
hogy két n-jegyő szám összege legfeljebb n + 1 -jegyő, és lehetséges, hogy az összegben tényleg szükség van ennyi jegyre). Mindkét számot és az összegüket is a számjegyeik sorozatával adjuk meg. Legyen a (1) = a n(1−)1 K a 0(1) , a (2 ) = a n(2−)1 K a 0(2 ) , és s = s n s n −1 K s 0 . A feladat az, hogy a és b ismeretében határozzuk meg s-t, vagyis másként, az adott a i(1) , a i(2 ) bináris jegyek, és ezen jegyek a (1) -beli és a (2 ) beli elhelyezkedésének ismeretében számítsuk ki az s i bináris számjegyeket. Ha u = 1 = v , akkor u + v = 2 = 1 ⋅ 21 + 0 ⋅ 2 0 , ami azt jelenti, hogy amikor két bitet (közönséges, aritmetikai értelemben) összeadunk, akkor átvitel keletkezhet, amelyet a következı, az elızıtıl eggyel balra esı pozíció számításakor figyelembe kell venni. Elsıként lássuk be, hogy az átvitel bármely pozíción csak 0 vagy 1 lehet. Legyen az i-edik helyen figyelembe veendı, azaz az i − 1 -edik helyen keletkezett átvitel ci −1 . Ha egy n > k ∈ N indexre 0 ≤ ck −1 ≤ 1 , akkor
0 ⋅ 21 + 0 ⋅ 20 = 0 = 0 + 0 + 0 = ak(1) + ak(2 ) + ck −1 ≤ 1 + 1 + 1 = 3 = 1 ⋅ 21 + 1 ⋅ 20 , így c k is csupán 0 vagy 1 lehet. Ez azt mutatja, hogy s i három bitbıl keletkezik, és hasonlóképpen c i is, és mindkettı értéke 0 vagy 1, vagyis mind s i , mind c i lényegében véve háromváltozós Boolefüggvény. Írjuk fel a megfelelı függvényeket. A 6. Táblázat mutatja a két függvényt.
a i(1) a i(2 ) ci −1 a i(1) + ai(2 ) + ci −1 s i c i 0 0 0 0 1 1 1 1
0 0 1 1 0 0 1 1
0 1 0 1 0 1 0 1
0 = 0 ⋅ 21 + 0 ⋅ 2 0 1 = 0 ⋅ 21 + 1 ⋅ 2 0 1 = 0 ⋅ 21 + 1 ⋅ 2 0 2 = 1 ⋅ 21 + 0 ⋅ 2 0 1 = 0 ⋅ 21 + 1 ⋅ 2 0 2 = 1 ⋅ 21 + 0 ⋅ 2 0 2 = 1 ⋅ 21 + 0 ⋅ 2 0 3 = 1 ⋅ 21 + 1 ⋅ 2 0
0 1 1 0 1 0 0 1
0 0 0 1 0 1 1 1
6. Táblázat
A táblázatból felírható a két Boole-függvény algebrai alakban:
s i = a i(1) a i(2 ) ci −1 + a i(1) a i(2 )c i −1 + a i(1) a i( 2 ) ci −1 + a i(1) a i(2 ) ci −1 ci = a i(1) a i(2 ) c i −1 + a i(1) a i(2 ) ci −1 + a i(1) a i(2 ) ci −1 + a i(1) a i(2 )c i −1
LOGIKAI ALGEBRA
82
ahol + és ⋅ (ez utóbbi helyett az egyszerő egymás mellé írás) a logikai mőveleteket, a logikai összeadást és logikai szorzást jelöli. Ezek a felírások mutatják, hogy ha alkalmas berendezéssel meg tudjuk valósítani a logikai összeadást, szorzást és a negálást, akkor olyan készüléket is tudunk konstruálni, amellyel két n-bites szám összegét realizáljuk. Most némi átalakítást végzünk a fenti kifejezéseken:
(
)
s i = a i(1) a i(2 ) ci −1 + ai(1) a i(2 ) ci −1 + a i(1) a i(2 ) ci −1 + a i(1) a i(2 ) ci −1 = a i(1) ⊕ a i(2 ) ⊕ ci −1 ugyanis mindkét oldalon pontosan akkor kapunk 1-et, ha a i(1) , a i(2 ) és ci −1 közül páratlan számúnak az értéke 1, és
ci = ai(1)ai(2 )ci −1 + ai(1)ai(2 )ci −1 + ai(1)ai(2 )ci−1 + ai(1)ai(2 )ci −1 = (ai(1) ⊕ ai(2 ) )ci −1 + ai(1)ai(2 ) ami ismét úgy ellenırizhetı a legkönnyebben, hogy mindkét oldali kifejezés pontosan akkor 1, ha a három változó közül legalább kettınek az értéke 1. Most legyen két kétváltozós Boole függvényünk, f (⊕ ) és f (|) , ahol f (⊕ ) ( x1 , x 0 ) = x1 ⊕ x0 és f (| ) (x1 , x 0 ) = x1 x 0 . Ekkor
(
)
(
(
)
s i = a i(1) ⊕ a i(2 ) ⊕ c i −1 = f (⊕ ) f (⊕ ) a i(1) , a i(2 ) , ci −1
( (
(
)
)
(
ci = f (| ) f (| ) f (⊕ ) a i(1) , a i(2 ) , ci −1 , f (|) a i(1) , a i(2 )
)
))
ugyanis (a b )(c d ) = ab + cd . Ha tehát van egy olyan berendezésünk, amely a-ból és b-bıl kiszámítja
f (⊕ ) (a, b ) = a ⊕ b -t és f (| ) (a, b ) = a b -t, akkor két ilyen eszköz, valamint egy NAND segítségével elı tudjuk állítani az összeg i-edik helyiértékén keletkezı jegyet, valamint az ugyanezen pozíción elıálló átvitelt. Az ilyen eszköz neve félösszeadó (angolul Half Adder, rövidítve HA) és a két félösszeadóból, valamint a NAND-et realizáló áramkörbıl álló, az összegbitet és átviteltbitet elıállító berendezés a teljes összeadó (angolul Full Adder, rövidítve FA). f (⊕ ) több különbözı kifejezéssel elıállítható, egy lehetséges változat például
(
)(
f (⊕ ) ( x1 , x0 ) = x1 ⊕ x0 = x1 (x1 x0 ) (x1 x0 ) x0
)
(sikerült egy egyszerő kifejezésbıl egy jó bonyolultat elıállítani, de egy rajz segítségével látjuk majd, hogy nem olyan szörnyő a helyzet). Valóban,
(x (x x )) ((x x ) x ) 1
1
0
1
0
akkor és csak akkor 1, ha
0
x1 (x1 x 0 ) és (x1 x0 ) x0 valamelyike 0. A NAND értéke pontosan akkor 0, ha mindkét tagja 1, így x1 (x1 x 0 ) pontosan akkor lesz 0, ha mind x1 , mind x1 x0 értéke 1. Ez utóbbi viszont x1 = 1 esetén csak úgy lehet, ha x 0 = 0 . Hasonlóan kapjuk, hogy (x1 x0 ) x0 is akkor és csak akkor 0, ha a két változó
(
)(
)
közül pontosan az egyik 1, tehát tényleg igaz, hogy x1 ⊕ x0 = x1 (x1 x0 ) (x1 x0 ) x0 . Természetesen algebrailag is ugyanezt az eredményt kapjuk:
x1 x0 = x1 x0 = x1 + x0 x1 (x1 x0 ) = x1 ( x1 + x0 ) = x1 x0 = x1 + x0
(x x ) x = (x + x )x 1
0
0
(x (x x )) ((x x ) x ) = (x + x )(x + x ) = x + x 1
1
0
1
0
0
1
0
1
0
1
0
1
0
0
= x1 x0 = x1 + x0
+ x1 + x0 = x1 x0 + x1 x0 = x1 ⊕ x0
Számítógépi matematika
83
Szemléletesen is megadjuk a fél- és teljes összeadót. Jelölje az ÉS-t a 27. ábra szimbóluma. A
& C
B
27. ábra
Ez azt jelenti, hogy a doboz két bemenetére kerül A és B, mindkettı értéke – egymástól függetlenül – 0 vagy 1, és a kimeneten megjelenı, C-vel jelölt jel értéke C = AB (& jelöli a logikai szorzást). Állapodjunk még meg abban, hogy ha valahol egy kis karika látható, az a megfelelı jel negálását jelenti, vagyis a következı ábrán elıbb a szorzat értékét változtatjuk ellentettjére, tehát C = AB = A B (ez tehát a Sheffer-vonás), a másikon pedig C = AB (ami egy inhibíció), ahogy a 28. ábra mutatja. A
A
&
&
C
C
B
B
28. ábra
Ekkor a félösszeadó ábrája a következı (29. ábra):
&
A &
A⋅ B
&
A⋅ B
&
A⋅ B + A⋅ B
A⊕ B
A⋅ B
B AB 29. ábra
(persze azt nem állítottuk, hogy ez az egyetlen lehetıség, hiszen ugyanazt a logikai függvényt több, egymástól különbözı kifejezés is megvalósítja, amint korábban már láttuk).
ai
ai ⊕ bi
HA
ai bi
bi
a i ⊕ bi ⊕ c i −1
HA
si
(ai ⊕ bi )ci −1
ci-1 &
(ai ⊕ bi )ci −1 + a i bi
30. ábra
ci
LOGIKAI ALGEBRA
84
A teljes összeadó két félösszeadó megfelelı összekapcsolásával alakítható ki, ezt mutatja a 30. ábra. Hogy ez valóban kiadja az összeg i-edik bitjét és a következı (magasabb) helyiértékre való átvitelt, az a félösszeadó mőködésének ismeretében – a két részábra jeleinek figyelembevételével – könynyen adódik. sn
sn −1
s1
s0
FAn-1
FA1
FA0
an(2−)1an(1−)1
a0(2a)0(1)
a0(2 )a0(1)
c
31. ábra
ai(1)
ai(2 )
c−1
(
ai(1) ⊕ ai(2 ) ⊕ c−1
HA
(
ai(1) ai( 2 ) ⊕ c−1
HA
i −1
(a ( ) ⊕ (a ( ) ⊕ c ))c
+ ai(1) ai(2 ) ⊕ c−1
1
&
2
i
1
i
ci −1
)
(a ( ) ⊕ (a ( ) ⊕ c ))⊕ c i
HA
)
2
i
−1
−1
i −1
(
)
32. ábra
Ha n-darab ilyen teljes összeadót láncba kapcsolunk, akkor egy n-bites összeadót kapunk, amit a 31. ábra mutat. Még egy kicsit bıvítve a teljes összeadót, nézzük a 32. ábra elrendezését. Ha c −1 = 0 , akkor a négy kimeneten sorban a i(1) ⊕ a i(2 ) , a i(1) a i(2 ) , s i és c i lesz, vagyis az összeadáson kívül megvalósítottuk a bitenkénti logikai szorzást és kizáró vagyot. Ha viszont c −1 = 1 , akkor ha a i(1) = 0 , úgy a legfelsı kimeneten a i(2 ) + 1 = a i(2 ) lesz, tehát tudunk bitenként negálni. Nézzük még meg, hogy mit kapunk c −1 = 1 esetén az alulról második kimeneten, vagyis ott, ahol az elıbb az összeadás aktuális bitje jelent meg. Elıször legyen a i(1) = 0 . Ha eltekintünk ci −1 -tıl, akkor ezen a kimeneten is
a i(2 ) + 1 = a i(2 ) van, vagyis a i(2 ) ellentettje. De c −1 = 1 tulajdonképpen azt jelenti, hogy N 2 legalacsonyabb helyiértékő jegyéhez hozzáadunk 1-et. Ha most figyelembe vesszük a ci −1 átvitelbiteket is, akkor végül is az történt, hogy N 2 valamennyi bitjét az ellentettjére változtattuk, és az így kapott számhoz hozzáadtunk 1-et. Ez viszont, ha eltekintünk a legmagasabb helyiértéken keletkezı átviteltıl, nem más, mint N 2 2 n -re vonatkozó komplemense, tehát a berendezésünkkel komplementálni is tudunk. Ha most még elhagyjuk azt a kikötésünket is, hogy az elsı operandus értéke legyen 0, akkor
Számítógépi matematika
85
c −1 = 1 esetén N 1 -hez hozzáadtuk N 2 2 n -re vonatkozó komplemensét, és ezzel megvalósítottuk a kivonást. Azt látjuk tehát, hogy ezzel a berendezéssel meg tudjuk valósítani a bitenkénti negálást és bitenkénti logikai szorzást, de akkor ezek segítségével a logikai összeadást is, létre tudjuk hozni a bitenkénti modulo 2 összeget, két n-bites szám összegét és különbségét. A léptetést nyilván könnyő megvalósítani, tehát akkor már szorozni és osztani is tudunk, ami mutatja, hogy pusztán a NAND mővelet felhasználásával lényegében véve a számítógép teljes aritmetikai-logikai egysége felépíthetı.
Most tekintsük a következı ábrát:
&
R
&
bm
WEn
&
&
Q
& t n,m
S
REn 33. ábra
Nézzük elıször a belsı bekeretezett részt. Ennek a berendezésnek a mőködéséhez kössük ki, hogy RS = 0 , vagyis R és S egyszerre nem lehet 1, továbbá azt, hogy a készülékünk csak meghatározott diszkrét idıpontokban változtathatja meg az állapotát. Jelöljük az n-edik idıpontban a kimeneten megjelenı értéket Q (n ) -nel, és nézzük, hogy mi jelenik meg ezen a ponton az n + 1 -edik idıpontban. Elsıként legyen R = 1 , és ekkor az elıbbi kikötésnek megfelelıen S = 0 . Mivel R = 1 , ezért R = 0 , és akkor a felsı NAND-kapu kimenetén biztosan 1 jelenik meg. Ez az 1 rákerül az alsó NAND felsı pontjára, és az alsó pontra S = 1 , vagyis a NAND mindkét bemenetén 1 van, és így a kimenetén 0 jelenik meg. Ez azt jelenti, hogy bármi is volt Q (n ) , Q (n +1) biztosan 0 lesz. Amennyiben S = 1 (és akkor R = 0 ), akkor S = 0 , és Q (n +1) = 1 . Végül nézzük, hogy mit kapunk a kimeneten, ha mind R, mind S nullával egyenlı. A felsı kapu kimenetén 0 ⋅ Q (n ) = Q (n ) lesz, és így az alsó kapu kinenetén 0 ⋅ Q (n ) = Q (n ) jelenik meg, ami azt jelenti, hogy nem változik a kimenet, Q (n +1) = Q (n ) . Az így elıállított függvény táblázata a következı: RS Q (n +1)
00 Q (n ) 01
1
10
0
11
−
7. Táblázat
Ez a következıt jelenti: ha egyszer S = 1 , akkor utána mindaddig, amíg R = 1 nem kerül a bemenetre, a függvény értéke 1, még akkor is, ha közben S értéke is 0 lesz, majd R = 1 hatására 0 jelenik meg a kimeneten, és mindaddig ırzi ezt az értéket, amíg az S bemenetre 1-et nem adunk.
86
LOGIKAI ALGEBRA
Térjünk rá a teljes rajz vizsgálatára. Legyen most WE olyan jel, amely csupán a t i idıpillanatokban lehet (de akkor sem mindig) τ ideig 1, majd valamennyi – de nullánál hosszabb – ideig 0, és legyen b egy bit, továbbá S = WE ⋅ b , R = WE ⋅ b . Az láthatóan teljesül, hogy RS = 0 . Ha b = 1 , akkor S = 1 , tehát Q = 1 lesz, míg ha b = 0 , akkor Q értéke biztosan 0 lesz mindaddig, amíg b ismét 1-re nem változik. Azt látjuk, hogy az áramkör a kimenetén ırzi b legutolsó értékét, vagyis ha ezt a függvényt realizáljuk, akkor egy bit tárolására alkalmas berendezést nyerünk. A külsı keret által meghatározott rész tehát egy egybites memóriacella. Ha a memóriában egy szó hossza s bit, és összesen w szó a memória kapacitása, akkor s ilyen cella alkot egy szót, mondjuk az n-ediket. Ennek a szónak valamennyi cellájába egyszerre kell beírni az adatot, és egyszerre kell kiolvasni belıle, továbbá egy adott idıpontban legfeljebb csak egy szóba írunk illetve egyetlen szót olvasunk, és ez a két esemény is másmás idıpontban aktuális. Ezt vezérli WE n és RE n : WE n akkor lesz 1 egy rövid idıre, amikor az n-edik szót írni akarjuk, míg RE n akkor, amikor ennek a szónak a tartalmát akarjuk kiolvasni. bm az s bitbıl az m indexő, vagyis s > m ∈ N (és w > n ∈ N ). WE n és RE n az n-edik szó minden cellájára közös, mint ahogy bm valamennyi szó m-edik bitjére azonos – hiszen legfeljebb csak egyre lesz hatása, tudniillik amelyikre a megfelelı WE -érték is 1. Ha egy rögzített m-hez tartozó t n , m értékeket összeszorozzuk, és az így kapott jelet negáljuk, akkor az így nyert jel értéke mindig 0, kivéve, ha valamelyik szóra, mondjuk az nedikre, RE értéke 1, és ekkor éppen t n , m -et kapunk, ami az n-edik szó m-edik cellájába utoljára beírt bit. Az ábrán a belsı bekeretezett rész végzi a tényleges tárolást, az elıtte lévı rész pedig biztosítja, hogy R és S egyszerre ne legyen 1, és csak akkor változhasson a tároló tartalma, ha WE n értéke 1. Könnyő megadni WE n -t és RE n -t: WE n = WE ⋅ Cím n és RE n = RE ⋅ Cím n , ahol WE = WR ⋅ C p és
RE = RO ⋅ C p . Itt C p az órajel, amely szabályos idıközönként, tehát egy T periódussal, τ idıre 1, egyébként 0. WR jelzi a memóriának, hogy írni akarunk, míg RO , hogy olvasni, és Cím n az n-edik szó címjele, amely pontosan akkor 1, ha az n-edik szóba írunk vagy onnan olvasunk, és ennek értéke egy adott idıpillanatban legfeljebb csak egy n-re lehet 1. A korábban elmondottaknak megfelelıen WR ⋅ RO = 0 mindig teljesül. A fentiekben éppen azt láttuk be, hogy a legelemibb logikai mőveletek segítségével megvalósítható a számítógép mőveletvégzı és tároló egysége. A vezérlés eleve kötıdik a logikához, és nem túl sok munkával megmutatható, hogy az eddig ismertetett eszközökkel a teljes vezérlıegység is felépíthetı (kivételt az órajel elıállítása jelent), így végeredményben azt kaptuk, hogy szinte a teljes számítógép – elvileg – nem tartalmaz mást, mint a fejezetben ismertetett egyszerő berendezéseket, természetesen megfelelıen kapcsolatba hozva ezeket egymással.
87
A HIBAKORLÁTOZÁSRÓL Az adatok tárolás illetve átvitel során megváltozhatnak, meghibásodhatnak, ezért szeretnénk olyan eljárást megadni, amellyel kiolvasáskor illetve a vétel helyén észre tudjuk venni, hogy sérült az adat, sıt, amennyiben lehetséges, helyre tudjuk állítani az eredeti állapotot. A fenti cél megvalósítását szolgálja a hibakorlátozás. Nyilván irreális kívánság, hogy bármely meghibásodást észrevegyünk, hiszen ha egy üzenet úgy sérül, hogy a megváltozott jelsorozat maga is egy értelmes üzenet, akkor semmilyen eszközzel nem vesszük észre a változást. Az is nyilvánvaló, hogy a javításhoz legalábbis észlelni kell a hibát, így minden hibajavító kód egyben jelezni is képes a hibát, de ez visszafelé nem igaz. Ahhoz ugyanis, hogy javítani tudjunk, ahhoz a hiba észlelésén túl azt is tudni kell, hogy az üzenet mely pontján történt a hiba, és milyen hiba lépett fel. Ez utóbbi feltétel automatikusan teljesül, ha az üzenet kódja bináris, hiszen ekkor a meghibásodás azt jelenti, hogy ha a vétel helyén 1-est olvasunk, és tudjuk, hogy ez a bit hibás, akkor az eredeti jegy csakis 0 lehetett, és fordítva. Mivel a hibakorlátozás szempontjából elvileg közömbös, hogy adattárolásról vagy adatátvitelrıl van szó, ezért bármelyikrıl is szólunk, az a másikra is érvényes. Tegyük fel, hogy az eredeti adatok egy-egy tetszıleges bájtot jelentenek. Ekkor persze semmilyen hibajelzés nem valósítható meg, hiszen bárhol is sérül a bájt, ismét egy érvényes adatot, nevezetesen egy bájtot kapunk. Egészítsünk ki minden bájtot egy kilencedik bittel oly módon, hogy a kilenc bitbıl vagy páros, vagy páratlan számú legyen 1 (de mindegyik bájtot azonos rendszer szerint, vagyis vagy mindegyiket párosra egészítjük ki, vagy mindegyiket páratlanra, elıre rögzített, és a vétel helyén is ismert módon). Ez azt jelenti, hogy ha az eredeti bájt b0b1b2b3b4b5b6b7 volt, ahol minden 7 ≥ i ∈ N 0 -
(
)
ra bi ∈ {0,1} , akkor b8 = ⊕ i7= 0 bi ⊕ c , ahol ⊕ modulo 2 összeadást jelent (tehát 0 az értéke, ha a közönséges összeg páros, és 1, ha a szokásos összeg páratlan), és c éréke 0, ha páros számú 1-re akarunk kiegészíteni, míg c = 1 az ellenkezı esetben. b8 az úgynevezett paritásbit. Ha most az átvitel során egy bit meghibásodik, akkor az egyesek számának paritása (vagyis hogy ez a szám páros illetve páratlan) az ellenkezıjére változik, és ezt a vétel helyén az egyesek leszámlálásával könnyen ellenırizni tudjuk, bármelyik bit is hibásodott meg (tehát akár a paritásbit is lehet hibás), a rendszer egyetlen hibát biztosan észrevesz, és így jelez. Két hiba esetén azonban az egyesek számának paritása változatlan, hiszen vagy két nulla változott 1-re, vagy két 1-es nullára, és mindkét esetben az 1-esek száma kettıvel változott, vagy egy 0 1-re, egy 1-es pedig 0-ra változott, amikor az 1-esek száma változatlan, így két hibát ez a rendszer biztosan nem jelez. A fentiek egyszerő folytatásaként könnyő belátni, hogy ez a módszer minden olyan esetben jelez, amikor egy kiegészített bájtban páratlan számú bit hibásodik meg, és soha nem jelez, ha a meghibásodott bitek száma páros. Azt is könnyen beláthatjuk, hogy ez a kódolás hibajavításra nem alkalmas, hiszen csak annyit tudunk, ha egyáltalán tudunk (vagyis ha páratlan számú hiba történt), hogy a kapott adat biztosan nem azonos a küldeménnyel, de bármely bit meghibásodása ugyanolyan eredményt ad, így semmiképpen nem tudjuk megállapítani, hogy melyik bittel történt a baj. Ezt a hibakorlátozást így fıleg olyan helyen érdemes alkalmazni, ahol a hibák egymástól függetlenül lépnek fel, és igen kicsi a hiba valószínősége, továbbá hiba esetén lehetıség van ismétlésre. Ezeknek a kívánalmaknak többé-kevésbé megfelel a számítógép operatív memóriája, így ezekben szinte mindig ezt a fajta hibakorlátozást alkalmazzák, mégpedig a páratlanra való kiegészítéssel. Amikor bekapcsoljuk a számítógépet, és a képernyın egyre növekvı számot látunk, akkor a gép memóriáját ellenırzi oly módon, hogy ismert 9 bites adatot ír a memória minden rekeszébe, majd kiolvassa, és megnézi, hogy azt kapta-e, amit adott. A normális mőködés során minden alkalommal, amikor a gép memóriájába egy bájt beírása történik, a gép automatikusan kiszámítja a bájthoz tartozó paritásbitet, és ezzel együtt tárolja az adatot, majd kiolvasáskor ellenırzi, hogy a 9 bit paritása páratlan-e, ha nem, akkor hibajelzést ad, míg ha igen, akkor elhagyja a 9. bitet, és átadja a további feldolgozásra. Az aszinkron adatátvitelnél is alkalmazzák az egyszerő paritásbites ellenırzést; ilyenkor szokásos a párosra való kiegészítés is. Bıvítsük az elıbbi módszert. Legyen egy adatblokkunk, amelyben minden bájtot egy-egy paritásbittel látunk el az elıbbi módon. Egymás alá írva a blokk így kiegészített bájtjait, kilenc oszlopot kapunk. A korábbiakhoz hasonlóan minden oszlopot egészítsünk ki alul egy-egy paritásbittel:
A hibakorlátozásról
88 b0, 0 M
K
bi ,0 K M bn −1,0 K bn , 0 K
b0 , j M
K
bi , j K M bn−1, j K bn, j K
b0,7 M
b0,8 M
bi ,7 M bn−1, 7 bn ,7
bi ,8 M bn −1,8 bn ,8
(
)
ahol n > i ∈ N 0 -ra bi,0bi,1bi,2bi,3bi,4bi,5bi,6bi,7 a blokk i-edik bájtja, és bi ,8 = ⊕ 7j =0 bi , j ⊕ cV ennek a bájtnak a paritásbitje (cV minden bájt esetén azonos), míg 8 ≥ i ∈ N 0 -ra bn, j =
(
⊕ in=−01
)
bi , j ⊕ c L az úgyne-
vezett ellenırzı bájt (szokás az egyes bájtok ellenırzését végzı paritásbiteket VRC-nek nevezni, ami a Vertical Redundancy Check kezdıbetőibıl álló rövidítés, és ami vízszintes vagy kereszt irányú ellenırzést jelent, míg az ellenırzı bájt az LRC, azaz Longitudinal Redundancy Check, a függıleges, vagyis hosszirányú ellenırzés). Ez a rendszer egyetlen hiba esetén képes azt javítani. Ha ugyanis bi,j és csak ez a bit hibás, akkor pontosan egy hiba van az i-edik bájtban, tehát ennek ellenırzése során hibajelzést kapunk, az összes többi bájt ellenırzése azt adja, hogy azokban nincs hiba, és hasonlóan, a jedik és csak a j-edik oszlop ellenırzésénél hibajelzésre kerül sor, vagyis a két eredménybıl azt kapjuk, hogy az i-edik bájt j-edik bitje és csak ez a bit hibás, amit ennek a bitnek az invertálásával kijavíthatunk. Minden olyan esetben azonban, amikor az i-edik és csak az i-edik bájtban valamint a j-edik oszlopban és csak a j-edik oszlopban kapunk hibajelzést, azt gondoljuk, hogy ez a bit hibásodott meg, és ezt “javítjuk”, vagyis változtatjuk az ellenkezıjére, pedig könnyen beláthatjuk, hogy ellenırzéskor ugyanerre az eredményre jutunk akkor is, ha minden oszlopban és minden bájtban, kivéve a j-edik oszlopot és i-edik bájtot, páros számú hiba lép fel (ebbe beleértve a hibátlan esetet is 0 hibával), míg a kitüntetett i-edik bájtban és j-edik oszlopban a hibák száma páratlan, tehát ha például az i-edik bájtban a j-edik és a j + 1 -edik bit, valamint az i + 1 -edik bájt j + 1 -edik bitje hibásodik meg, és más hiba nem történik. A vétel helyén semmilyen módszerrel nem tudjuk eldönteni, hogy valóban egy hiba történt-e, és így helyesen javítunk, vagy a megfigyelt hibajelzés több hiba együttes hatása, aminek következtében vagy egy addig helyes bitet javítunk helytelenre, vagy egy tényleg hibás bitet javítunk, de még további, felderítetlen hiba is van a vett üzenetben. Hasonlóan elıfordulhat, hogy volt hiba, de mi nem vesszük észre, nevezetesen ha minden bájtban és minden oszlopban a hibák száma páros; ennek tipikus példája, amikor négy hiba egy téglalap négy sarkában lép fel, ahol a téglalap két éle egyegy bájtban van: Végül elıfordulhat, hogy egynél több bájtban, vagy/és egynél több oszlopban kapunk hibajelzést, amikor biztosan tudjuk, hogy volt hiba, de a hibák száma egynél nagyobb, így javításra ebben a rendszerben nincs lehetıségünk; ennek legegyszerőbb példája, amikor pontosan két hiba lép fel. A most ismertetett rendszert nevezhetjük kétdimenziós paritásellenırzésnek; ilyet használnak nagy mágnesszalagos tárolóknál (egy bizonyos rögzítési mód esetén, mert többféle is létezik), ahol egymás mellé írják ki egy kiegészített bájt 9 bitjét, és az adatokat mindig blokkosan tárolják (egyébként ilyenkor az LRC után még egy egy vagy két 9-bites bájtból álló további ellenırzı karaktert is kiírnak, ez az úgynevezett CRC, vagyis Cyclic Redundancy Check, ciklikus ellenırzés), ebben az esetben vízszintesen páratlanra, míg függılegesen párosra egészítenek ki, vagyis cV = 1 és c L = 0 , ilyenkor érdekes kérdés, hogy az ellenırzıbájt 8-as indexő bitjének értéke azonos-e, ha vízszintesen és függılegesen számítjuk, és ha nem, akkor milyen cV és c L érékeknél lesz az így számított két érték biztosan azonos, illetve ha nem mindig azonos, akkor milyen további feltételtıl függ az egyezés, ám ezeket a kérdéseket házi feladatnak hagyjuk. Egy további hibajavító kódot ismertetünk, az úgynevezett Hamming-kódot, amely szintén egy hiba javítására alkalmas. Legyen r ≥ 2 egész szám, n = 2 r − 1 , és k = n − r . Most készítsük el azt az r × n mérető H mátrixot, amelyben az n ≥ j ∈ N indexre a j-edik oszlopban a j szám kettes számrendszerbeli felírásának jegyei találhatóak, vagyis ha j = ∑i =0 a i( j ) 2 i , akkor a mátrix i-edik sorának jr −1
edik oszlopában, ahol r > i ∈ N 0 és n ≥ j ∈ N , H i , j = a i( j ) áll (mivel j ≤ n < 2 r , ezért j biztosan felír-
Számítógépi matematika
89
ható r jeggyel a bináris számrendszerben). Legyen például r = 3 , akkor n = 7 és k = 4 , továbbá 1 0 1 0 1 0 1 H = 0 1 1 0 0 1 1 . Mivel r > t ∈ N 0 esetén 2 t kettes számrendszerben való felírása olyan, amely0 0 0 1 1 1 1 ben a 0-tól kezdıdı indexelés mellett a t-edik és csak a t-edik jegy 1, az összes többi 0, ezért a H mátrix t darab oszlopa, amelyek a 2 t indexhez tartoznak, egy egységmátrixot adnak (az elıbbi példában az 1., a 2. és 4.), így a mátrix rangja legalább r, ugyanakkor annál nagyobb nem lehet, hiszen r sora van, vagyis rang(H ) = r . Legyen most c T = c1 K c n egy n-mérető sorvektor, amellyel Hc = 0 , ahol c az elıbbi c T -hez tartozó oszlopmátrix, és 0 az r-mérető, csupa 0-ból álló oszlopmátrix (a mőveleteket modulo 2 végezzük). Az elıbbi mátrixegyenlet ekvivalens egy r egyenletbıl álló n-ismeretlenes homogén lineáris egyenletrendszerrel, és mivel az együtthatómátrix rangja r, ezért az n darab c i közül n − r = k darab szabadon választható, például azok, amelyek indexe nem 2 t -alakú, és akkor a maradék r komponens, például a 2 t indexekhez tartozók, egyértelmően meghatározhatóak. Tekintsük a
{
}
C = (c1 K c n ) n ≥ i ∈ N : ci ∈ {0, 1} ∧ Hc = 0 halmazt, vagyis azon n-dimenziós bináris vektorok halT
mazát, amelyeknek H-val vett szorzata 0. Láttuk, hogy az ilyen vektorokban k komponens szabadon választható (persze nem bármelyik k, csak azok, amelyekkel a kimaradt komponensekhez tartozó indexek H reguláris részmátrixát határozzák meg, például a fenti példán nem jó választás az utolsó négy komponens, mert a mátrix elsı három oszlopa lineárisan összefüggı), legyenek ezért a kódolandó üzenetek k bitesek, és egy-egy ilyen üzenetet egészítsünk ki r bittel úgy, hogy a kapott n-bites vektor eleme legyen a C halmaznak. Tegyük fel, hogy egy ilyen n-bites üzenet az átvitel során megsérül. Ez azt jelenti, hogy bizonyos bitek az ellenkezıjükre változnak, amit úgy is megkaphatunk, ha ezekhez az eredeti bitekhez 1-et adunk modulo 2 (hiszen 0 ⊕ 0 = 0 = 1 ⊕ 1 és 0 ⊕ 1 = 1 = 1 ⊕ 0 ),vagyis tegyük fel, hogy c T az eredeti n-bites vektor, és e T = e1 K en a hibavektor, akkor a vétel helyére v T = c T + e T érkezik. Számítsuk ki a Hv szorzatot. Mivel Hc = 0 , és a mátrixszorzás disztributív az összeadásra nézve, ezért Hv = H (c + e ) = Hc + He = He . Ha a H mátrix j-edik oszlopát h j -vel jelöljük, akkor az elıbbi eredményt felhasználva Hv = He = ∑ j =1 h j e j = ∑e n
j
=1
h j , hiszen ei értéke csak 0 és 1 lehet.
Ha pontosan egy hiba lépett fel, akkor egy és csak egy indexre, mondjuk s-re lesz e j nullától különbözı, és ekkor Hv = h s . De H konstrukciója következtében h s éppen s kettes számrendszerbeli felírása, vagyis Hv éppen a hiba helyét adja. Legyen például az elıbbi 3 × 7 -es H mátrixhoz c T = 0100101 , akkor ellenırizhetı, hogy Hc = 0 , vagyis c T kódszó, és tegyük fel, hogy e T = 0000100 , vagyis az 5. bit és csak ez a bit az üzenet átvitele során megsérül. Ekkor a vétel helyén 0 1 1 T a v = 0100001 bitsorozatot kapjuk, és ismét könnyő számolás mutatja, hogy Hv = 1 + 1 = 0 0 1 1 (az egyes komponensek összeadását modulo 2 végezzük). Ez mint bináris szám éppen öt, ami a hiba helye. Megváltoztatva a vett üzenetben az 5. bitet, a 0100101 bitsorozatot kapjuk, egyezésben az elküldött bitsorozattal. Nyitott még az a kérdés, hogy egy adott k-bites üzenethez hogyan tudjuk könnyen meghatározni az n-bites kódolt üzenetet. Legyen b1 K bk az üzenet. A kiszámítandó n-bites c T -ben a 2hatványnak megfelelı indexekhez tegyük a kiszámítandó biteket, vagyis legyen c-ben a 2 t -indexhez tartozó, egyelıre ismeretlen bit p t , és a többi helyre helyezzük el eredeti sorrendben a b vektor bitjeit. H-val szorozva ezt a vektort, egy egyenletrendszert kapunk, mégpedig olyat, hogy minden egyenletben pontosan egy ismeretlen szerepel, így azt könnyen ki tudjuk fejezni. A korábbi r = 3 esetben ez azt jelenti, hogy n = 7 , k = 4 , az üzenet b T = b1b2 b3 b4 , 3 ellenırzı bit lesz, és ezeket a 2 0 = 1 ,
A hibakorlátozásról
90
21 = 2 és 2 2 = 4 indexő helyekre rakjuk, vagyis c1 = p 0 , c 2 = p1 , c3 = b1 , c 4 = p 2 , c5 = b2 , c 6 = b3
és c7 = b4 . Konkrétan legyen az üzenet b T = 0101 . Ekkor c T = p 0 p1 0 p 2 101 , és a Hc szorzat, amelynek az értéke 0 kell, hogy legyen,
1 0 1 0 1 0 1 0 p0 0 + p1 1 + 0 1 + p 2 0 + 1 0 + 0 1 + 11 = 0 . 0 0 0 1 1 1 1 0 Átrendezés és kissé másként való írás után ebbıl azt kapjuk, hogy teljesülnie kell a
p0 1 1 0 1 0 p1 = 0 1 + 1 0 + 0 1 + 11 = 1 p 0 1 1 1 0 2 mátrixegyenletnek, azaz p 0 = 0 , p1 = 1 és p 2 = 0 , ahonnan c T = 0100101 (nem véletlenül a korábban már használt kódszót kaptuk). Ha az egyszerőbb írásmód kedvéért H oszlopait átrendezzük olyan sorrendben, hogy a bal szélén álljon az egységmátrix, amit a 2-hatványhoz tartozó indexek jelölnek ki, és ettıl jobbra helyezkedik el H többi oszlopa az eredeti sorrendben, akkor
p0 ' M = ∑b j =1 h j +t p r −1 1 0 0 1 1 0 1 ahol h i az átrendezett mátrix i-edik oszlopa. Ismét az elıbbi példával H = 0 1 0 1 0 1 1 az át0 0 1 0 1 1 1 T rendezett mátrix, és a b = b1b2 b3 b4 üzenethez tartozó paritásbitek
′
p0 1 1 0 1 b1 ⊕ b2 ⊕ b4 p1 = b1 1 + b2 0 + b3 1 + b4 1 = b1 ⊕ b3 ⊕ b4 . p 0 1 1 1 b ⊕ b ⊕ b 3 4 2 2 Az ellenırzést és a javítást már láttuk: megszorozzuk H-t a beérkezett n-essel jobbról, és a Hv által mint bináris számmal meghatározott helyen lévı bitet az ellenkezıjére változtatjuk, ha a szorzat értéke nem nulla. Ez az eljárás azonban ismét helytelen eredményre vezet, ha a hibák száma nagyobb, mint egy. Házi feladat annak meggondolása, hogy ha két hiba van, akkor egy, az elıbbi két helytıl különbözı harmadik helyen, azaz egy hibátlan bitet javítunk, míg ha három hiba van, akkor elıfordul, hogy a szorzat értéke 0, vagyis azt hisszük, hogy nem volt hiba, míg ha a szorzat nem nulla, akkor biztosan egy negyedik helyen “javítunk”. Minden esetre az esetleges (néha hibás) javítás után a kódszóról leválasztva a paritásbiteket, visszakapjuk az eredeti üzenetet (feltéve, hogy legfeljebb egy hiba volt, és így helyesen dekódoltunk). Ismét a korábbi példával, ha a vett bitsorozat, amint láttuk, 0100001 , akkor javítás után a 0100101 kódszót kaptuk, és leválasztva a paritásbiteket, amelyek ebben a sorozatban az 1., 2. és 4. helyen állnak, kapjuk a 0101 üzenetet. Ha viszont eredetileg ismét ez volt az üzenet, de az átvitel során a 3. és 7. bit sérül, akkor v T = 0110100 , ezt H-val szorozva 0 Hv = 0 , ezért átfordítjuk v-ben a 4. bitet, ekkor azt kapjuk, hogy 0111100 , és kihámozva az üze1
Számítógépi matematika
91
netbiteket azt gondoljuk, hogy az eredeti üzenet 1100 , ami hibás eredmény. Konklúzióként azt mondhatjuk, hogy a Hamming-kód ismét viszonylag kis hibavalószínőség esetén alkalmazható. A Hamming-kódhoz az eredeti üzenetek hossza olyan k érték kell, hogy legyen, amelyhez van olyan pozitív egész r, amellyel k = 2 r − r − 1 (ilyen például 4, 11, 26, 57 stb). Ez nem feltétlenül szükséges: ha k nem ilyen érték, akkor megfelelı számú nullával kiegészítve, kódolás után ezeket a nullákat elhagyhatjuk, míg dekódolás elıtt ismét beírjuk ıket, és dekódolás után megint eldobjuk. Eddig két olyan kódot ismertettünk, amelyek 1 hiba esetén helyesen javítottak, de két hibát nem. Vannak az elıbbieknél bonyolultabb kódok, amelyek több hiba esetén is helyesen javítanak, ezekkel azonban itt nem foglalkozunk.
93
PÉLDÁK 1. Adjuk meg N = 941,2310 elıjel nélküli kódját, ha r = 7 , és a)
n = 8 és i. m = 0 ii. m = 3 iii. m = 7 iv. m = 8 v. m = 13 vi. m = −2 vii. m = −5
b) n = 16 és m = 5 Megoldás: Elıször átírjuk a számot a 7-es számrendszerbe:
541 134 3 19 1 2 5 0 1 4 1 6 1 4 1 6 1 4 1 6 .
23 61 27 89 23 61 ← innen kezdve ismétlıdik az eddigi szakasz 27 89 23 61 27 89 23 .
vagyis 941,2310 = 2513, 1 41 6 7 . a) A kód összesen 8 jegyet tartalmaz i. A törtrész hossza 0: 0 0 0 0 2 5 1 3 ↑
ii.
A törtrész 3 jegyet tartalmaz:
0 2 5 1 3 1 4 1 ↑ iii. A törtrész jegyeinek száma 7: 3 1 4 1 6 1 4 1 ↑
PÉLDÁK
94 iv. A 7-edespont a kód bal szélén áll:
v.
1 4 1 6 1 4 1 6 ↑ A 7-edespont a kódszón kívül, attól 5 pozícióval balra helyezkedik el: 4 1 6 1 4 1 6 1
↑ vi. A 7-edespont a kódszón kívül, attól 2 hellyel jobbra áll:
0 0 0 0 0 0 2 5 ↑ vii. A 7-edespont a kódszó jobb szélétıl 5 pozícióval jobbra áll:
0 0 0 0 0 0 0 0 ↑ Láthatóan a iii.-v. esetekben értékes jegyek vesznek el a kódolás során. (Ha valakit izgat a matematika, akkor lássa be, hogy a törtrész periódusa tényleg 4 kell, hogy legyen.)
b) 0 0 0 0 0 0 0 2 5 1 3 1 4 1 6 1 ↑ 2. Írjuk fel N = 941,23010 -et a 7-es számrendszerben, ha N egy mérés eredménye. Megoldás: Elıször meg kell határozni, hogy hány jegyet tartalmazzon az átalakított szám. Az eredeti szám legalacsonyabb helyiértékő jegyének 1 egysége adja a szám pontosságát, és ez 10 −3 . Az átalakított szám pontosságának nagyságrendileg ugyanekkorának kell lennie, így ha a jobb szélsı jegy az sedik pozícióban áll (ahol s negatív, ha a szám törtrészt is tartalmaz), akkor 7 s ≤ 10 −3 < 7 s +1 . Innen −3 logaritmálással s ≤ −3 log 7 10 < s + 1 . s egész szám, ezért s = = −4 , és 941,23010 = 2513,1416 7 . lg 7
3. Adjuk meg N = 76932 10 4 bájtos BCD-kódját. Megoldás: Minden számjegyet külön-külön kódolunk binárisan 4 jeggyel, és az így kapott tetrádokat egymás mellé írjuk: 76932 10 = 0111 0110 1001 0011 0010 BCD . A tetrádokat hexadecimálisan írva a kód
0 0 0 7 6 9 3 2 Látható, hogy a kód hexadecimális felírásában az egyes jegyek rendre megegyeznek az eredeti szám megfelelı jegyeivel. Ez nem véletlen, hiszen a 16-os számrendszerben egy 16-nál kisebb egész szám kódja nyilván önmaga. 4. Adjuk meg N = 101 illetve N = −101 8- és 16 bites a) eltolt nullpontú kódját, ha K = 2 7 illetve K = 215 a két fenti hossznak megfelelıen b) elıjeles abszolút értékes kódját, ha K = 2 7 illetve K = 215 a két fenti hossznak megfelelıen c) komplemens kódját.
Számítógépi matematika
95
Megoldás: A változatosság kedvéért hexadecimálisan is kiszámoljuk a kódokat. Elıször átalakítjuk N-et:
101 50 25 12 6 3 1
1 0 1 0 0 1
101 6 5
vagyis 10110 = 1100101 2 = 6516 a) A 8-bites kódnál N-hez 2 7 = 10000000 2 = 8016 -ot kell hozzáadni, így a 101 kódja 65 01100101 + 10000000 illetve + 80 E5 11100101 (természetesen a két kód azonos: 1110 2 = E 16 és 01012 = 516 ), míg a − 101 kódja 80 10000000 − 01100101 illetve + 65 1B 00011011 A 16-bites kódokat hasonlóan kapjuk: 0065 0000000001100101 + 1000000000000000 illetve + 8000 8065 1000000001100101 8000 1000000000000000 − 0000000001100101 illetve + 0065 7F9B 0111111110011011 s =1− s
ϕ en(8 ) (101) ⇓
↓ 1 1 1 0 0 1 0 1
s =1− s
(8 ) (− 101) ϕ en
⇓
↓ 0 0 0 1 1 0 1 1
1 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 1 1 1 1 0 0 1 1 0 1 1 ↑ s s s s s s s s ↑ s s s s s s s s 144424443 144424443 8 8 ⇑ ⇑ s =1− s s = 1 − s (16 ) (16 ) ϕ en (101) ϕ en (− 101)
Az egymás alatt álló kódokból látjuk, hogyan lehet a 8 bites kódról közvetlenül áttérni a 16 bites kódra: a legmagasabb helyiértéken álló jegy átkerül az új kód bal szélsı pozíciójába, és az eredeti
PÉLDÁK
96
jegy helyére, valamint ettıl balra az áthelyezett jegyig az áthelyezett jeggyel ellentétes jegyet írunk (próbálják végiggondolni, hogyan lehet áttérni egy nagyobb hosszra abban az esetben, ha az eltolás értéke 2 n −1 − 1 , illetve mi a helyzet akkor, ha a nagyobb hosszról akarunk kisebb hosszra áttérni). A kódok (8 ) (101) = E516 ϕ en
(8 ) (− 101) = 1B16 ϕ en
(16 ) (101) = 806516 ϕ en
(16 ) (− 101) = 7F9B16 . ϕ en
b) A nem negatív szám elıjeles abszolút értékes kódja önmaga, míg a negatív szám kódja a szám abszolút értékének és K-nak az összege. Ez egyben azt is jelenti, hogy ha egy eltolt nullpontú kód eltolási értéke megegyezik az elıjeles abszolút értékes kódban megadott K-val, akkor egy negatív szám elıjeles abszolút értékes kódja azonos a szám abszolút értékének, azaz − 1 -szeresének eltolt nullpontú kódjával: ha N < 0 , akkor ϕ ea ( N ) = K + N = K + (− N ) = ϕ en (− N ) . A keresett kódok tehát (8 ) (101) = 6516 ϕ ea
(8 ) (− 101) = E516 ϕ en
(16 ) (101) = 006516 ϕ ea
(16 ) (− 101) = 806516 ϕ en
Ábrával: s
(8 ) (101) ϕ ea
s
⇓
(8 ) (− 101) ϕ ea
⇓
↓ 0 1 1 0 0 1 0 1
↓ 1 1 1 0 0 1 0 1
0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 ↑ 144424443 s ⇑ s ϕ ea(16 ) (101)
1 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 ↑ 144424443 s ⇑ s (16 ) ϕ ea (− 101)
c) Nem negatív szám komplemens kódja önmaga, azonos az elıjeles abszolút értékes kódjával. A negatív szám kódjához meghatározzuk abszolút értékének 2 n -re vonatkozó komplemensét:
0000000001100101
01100101
01100101
⇓
⇓
0000000001100101
10011010 vagy közvetlenül ⇓ ⇓ és 1111111110011010 illetve + 00000001 10011011 + 0000000000000001 1111111110011011 10011011 1111111110011011 n
illetve hexadecimális alakban a 16 4 -re vonatkozó komplemenst (feltéve, hogy n osztható 4-gyel): 65 ⇓
0065
65
⇓
9A vagy közvetlenül ⇓ és FF9A + 01 9B + 0001 9B
FF9B
Számítógépi matematika
97
Most a kódok a következık:
ϕ k(8 ) (101) = 6516
ϕ k(8 ) (− 101) = 9B16
ϕ k(16 ) (101) = 006516
ϕ k(16 ) (− 101) = FF9B16
Ábrával: s
ϕ k(8 ) (101)
s
ϕ k(8 ) (− 101)
⇓ ↓ 0 1 1 0 0 1 0 1
⇓ ↓ 1 0 0 1 1 0 1 1
0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 ↑ s s s s s s s s 144424443 8 ⇑ s (16 ) ϕ k (101)
1 1 1 1 1 1 1 1 1 0 0 1 1 0 1 1 ↑ s s s s s s s s 144424443 8 ⇑ s (16 ) ϕ k (− 101)
Még egyszer megadjuk az eltolt nullpontú kódot: s =1− s
ϕ en(8 ) (101)
s =1− s
⇓ ↓ 1 1 1 0 0 1 0 1
(8 ) (− 101) ϕ en
⇓ ↓ 0 0 0 1 1 0 1 1
1 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 1 1 1 1 0 0 1 1 0 1 1 ↑ s s s s s s s s ↑ s s s s s s s s 144424443 144424443 8 8 ⇑ ⇑ s =1− s s =1− s (16 ) (16 ) ϕ en (101) ϕ en (− 101) Az egymásnak megfelelı részeket egybevetve látjuk, hogy a két kód csupán a legmagasabb helyiértéken álló jegyben tér el egymástól. 5. Nézzük meg N = 1013 illetve N = −1013 elıjeles BCD-kódját. Erre két alakot adunk meg. Az IBM-gépekben alkalmazott kód s
s
↓ 0 1 0 1 3 C
↓ 0 1 0 1 3 D
míg az IEEE-szabvány szerinti kód s ↓ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 3
s ↓ 8 0 0 0 0 0 0 0 0 0 0 0 1 0 1 3
PÉLDÁK
98
6. A lebegıpontos kóddal folytatjuk. Adjuk meg N = ±137,4810 normalizált lebegıpontos kódját, ha a kód formátuma s
e
a
{ 144244 3 144444244444 3 1
5
10
a kitevı kódja eltolt nullpontú, a mantisszáé elıjeles abszolút értékes, mind a kitevıt, mind a mantiszszát binárisan kódoljuk, továbbá ha m ≠ 0 , akkor d t ≤ m < d t +1 , és a)
d = 2 , K = 2 4 , t = 2 , és a = m
b) d = 2 , K = 2 4 − 1 , t = −1 , és a = m c)
d = 16 , K = 2 4 , t = 0 , és a = m
d) d = 2 , K = 2 4 − 1 , t = 0 , és 1.a = m (vagyis a a mantissza abszolút értékének törtrészét tartalmazza) Megoldás: A mantissza ábrázolásához 10, illetve a d) esetben 11 bit áll rendelkezésre, ezért összesen ennyi bitet határozunk meg. Az egész rész 8 bittel kódolható, így a törtrészre 2 illetve 3 bit jut:
137 68 34 17 8 4 2 1
1 0 0 1 0 0 0
0 0 1 1
48 96 92 84
vagyis 137,4810 = 10001001,012 = 89,416 , ha a törtrész 2 bites, míg 137,4810 = 10001001,0112 = 89,616 a három bites esetben. a) 10001001,012 = 100,01001012 ⋅ 2 5 , és teljesül a 2 2 ≤ 100,01001012 < 2 3 feltétel, továbbá K + 5 = 16 + 5 = 21 . A kód 0 1 0 1 0 1 1 0 0 0 1 0 0 1 0 1
1 1 0 1 0 1 1 0 0 0 1 0 0 1 0 1
vagy hexadecimálisan ϕ l(16 ) (13,48) = 562516 és ϕ l(16 ) (− 13,48) = D62516 . b) 10001001,012 = 0,10001001012 ⋅ 2 8 , és most is igaz, hogy 2 −1 ≤ 0,10001001012 < 2 0 , továbbá K + 8 = 15 + 8 = 23 , így a kód 0 1 0 1 1 1 1 0 0 0 1 0 0 1 0 1
1 1 0 1 1 1 1 0 0 0 1 0 0 1 0 1
vagy hexadecimálisan ϕ l(16 ) (13,48) = 5E 2516 és ϕ l(16 ) (− 13,48) = DE 2516 . c) 89,416 = 8,9416 ⋅ 161 , és megint igaz, hogy 16 0 ≤ 8,9416 < 161 . A kitevı kódja ebben a feladatban K + 1 = 16 + 1 = 17 , vagyis a kód
Számítógépi matematika 0 1 0 0 0 1 1 0 0 0 1 0 0 1 0 1
99
1 1 0 0 0 1 1 0 0 0 1 0 0 1 0 1
azaz ϕ l(16 ) (13,48) = 462516 és ϕ l(16 ) (13,48) = C62516 d) Mivel a mantisszának csak a törtrészét ábrázoljuk, ezért most ábrázolni tudjuk az eredeti szám törtrészének harmadik bitjét is. 10001001,0112 = 1,00010010112 ⋅ 2 7 , és a jobb oldali alak mantisszája normalizált, ugyanis 2 0 ≤ 1,00010010112 ⋅ 2 7 < 21 . A kitevı kódjához K + 7 = 15 + 7 = 22 , tehát meg tudjuk adni a kódot: 0 1 0 1 1 0 0 0 0 1 0 0 1 0 1 1
1 1 0 1 1 0 0 0 0 1 0 0 1 0 1 1
azaz ϕ l(16 ) (13,48) = 584B16 és ϕ l(16 ) (13,48) = D84B16 7. A következıkben visszafelé számolunk, vagyis adott kódból határozzuk meg az eredeti adatot. Legyen a kód 16 bites, és ϕ ( N ) = B5A416 . Határozzuk meg N-t, ha a kód a) elıjel nélküli, és m = −2 b) eltolt nullpontú, és K = 215 − 1 c) elıjeles abszolút értékes d) komplemens e) BCD f) a korábban megadott lebegıpontos kódok közül d) Megoldás: A Horner-módszerrel B5A416 = ((11 ⋅ 16 + 5) ⋅ 16 + 10 ) + 4 = 46500 .
(
)
a) Elıjel nélküli szám kódja ϕ ( N ) = r m N mod r n , így a kódból az eredeti szám N =r
−m
ϕ (N ) , feltéve, hogy a kódolás során nem vesztek el jegyek. Most m = −2 , tehát a kódot
2
2 = 4 -gyel szorozni kell: N = 4 ⋅ 46500 = 186000 .
b) 46500 = ϕ ( N ) = K + N = 215 − 1 + N = 32767 + N -bıl N = 13733 c) Az eltolt nullpontú kódolás esetén K értéke a gyakorlatban mindig 2 n −1 , ahol n a kódszó hossza bitekben. A szám akkor és csak akkor nem negatív, ha a kódja kisebb, mint K. Most K = 215 = 32768 <= 46500 = ϕ ( N ) , így az eredeti szám negatív. Ekkor ϕ ( N ) = K + N , ahonnan megkapjuk az eredeti számot: N = −(ϕ ( N ) − K ) = −(46500 − 32768 ) = −13732 . d) n-bites komplemens kódban a nem negatív számok kódjában a legmagasabb helyiértéken álló bit 0, míg negatív szám kódjában 1 áll a bal szélsı pozícióban. A hexadecimális írás esetén ez ekvivalens azzal, hogy a legmagasabb helyiértéken álló hexadecimális jegy kisebb, illetve nagyobb vagy egyenlı, mint 8. Mivel a megadott kód bal szélsı jegye B ≥ 8 , így ismét negatív számot kódoltunk. Ekkor a kód a szám abszolút értékének komlemense, azaz ϕ ( N ) = 2 n − N . Ebbıl kifejezve N-t,
(
)
N = − 2 n − ϕ (N ) = −(65536 − 46500) = −19036 . Ugyanezt az eredményt kapjuk, ha a komplementálás szabályát alkalmazva meghatározzuk a szám abszolút értékét: B5A416 ⇒ 4A5C 16 , és ezt alakítjuk át decimális számmá: 4A5C 16 = ((4 ⋅ 16 + 10 ) ⋅ 16 + 5) ⋅ 16 + 12 = 19036 , és az eredeti adat ennek az ellentettje. Van egy további lehetıség is a komplemens kódból az eredeti szám visszaállítására. Legyen a
kód ϕ ( N ) = ∑i =0 a i 2 i . Mivel ϕ (N ) = s 2 n + N , ezért n −1
PÉLDÁK
100
N = ϕ ( N ) − s 2 n = a n −1 2 n −1 + ∑i =0 a i 2 i − s 2 n = − s 2 n −1 + ∑i =0 a i 2 i n −2
n −2
hiszen a komplemens kódban a legmagasabb helyiértéken álló bit éppen az elıjelet mutatja. A konkrét példában ϕ (N ) = B5A416 = 8000 16 + 35A416 , így a számot megkapjuk, ha 35A416 = 13732 10 -bıl kivonunk 8000 16 = 3276810 -at, azaz N = 13732 − 32768 = −19036 (és fellélegezhetünk, mert ugyanazt az eredményt kaptuk, mint a korábbi két esetben. e) A megadott érték nem lehet BCD-kód, ugyanis BCD-kódban legfeljebb csak a jobb szélsı jegy lehet 9-nél nagyobb (és ez is csak akkor, ha az IBM szerint elıjeles számot kódoltunk), most viszont két jegy is van, amely nem decimális. f) Írjuk fel a kódot bináris alakban: B5A416 = 1011010110 100100 2 . A bal szélsı bit a szám elıjele, vagyis a kód negatív számhoz tartozik. A következı 5 bit a kitevı 15-tel eltolt kódja. Mivel ez az 5 bit 01101 2 = 13 , ezért maga a kitevı − 2 . A mantissza egy egész jegyet tartalmaz, és a törtrésze a maradék 10 bit, így m = 1,0110100100 2 = 3,6110 ⋅ 2 −10 . A végeredmény N = −3,6110 ⋅ 2 −12 .
101
FELADATOK A feladatok elıtt ismertetjük az ANSI/IEEE 754-es lebegıpontos számábrázolási szabványt. A szabvány szerint a lebegıpontos számok kódja az alábbi: t-2
t-1
p
s
p-1
0
k
m
t p t-p-1 e Egyszeres pontosságú 32 23 8 127 Dupla pontosságú 64 52 11 1023 Kiterjesztett pontosságú 80 64 15 16383 Négyszeres pontosságú 128 112 15 16383 Példa 16 10 5 15
A kettıs vonal alatti értékek nem szerepelnek a szabványban, csupán a típusfeladatok példáiban lesznek ezek az értékek. Ha a típusfeladatok, vagy a vizsgán szereplı feladat szabványos lebegıpontos számábrázolást említ, akkor ott mindig a Példa sorában álló értékek érvényesek.
(
)
A szabvány szerint N = (− 1)s 1 + m ⋅ 2 − p 2 k −e , kivéve a kiterjesztett pontosságot, ahol N = (− 1) m ⋅ 2 2 , vagyis az utóbbi esetben a mantisszában a kettedespont m bal szélsı bitjének jobb oldalán, áll, míg a többi esetben m bal szélén, de ekkor a mantissza értéke ennél 1-gyel több. A szabvány megkülönbözteti a normalizált és a denormalizált alakot, a gépi nullát, valamint a végtelent és a nem számot. Normalizált a szám, ha 1 ≤ k ≤ 2e , denormalizált, ha k = 0 , és ebben az esetben s N = (− 1) m ⋅ 2 − p 2 − (e −1) , és m ≠ 0 . A gépi nulla esetén mind k, mind e nulla, és ez az alak felel meg a lebegıpontos nullának. Amennyiben k valamennyi bitje 1, és m = 0 , akkor ez (az elıjeles) végtelen, míg ha k csupa 1-bıl áll, de m ≠ 0 , akkor ez egy nem számnak a kódja. A fent elmondottakat példákkal illusztráljuk. A példában mindenütt a Példa szerint kódoltunk, és a kódot hexadecimálisan adjuk meg. − ( p −1) k − e
s
• • •
0000 16 : minden bit nulla, tehát ez a gépi nulla 8000 16 : a bal szélsı bit 1, az összes többi 0, így ez a negatív gépi nulla 000116 : most s = 0 , k = 0 és m = 1 . Mivel k = 0 , ezért ez denormalizált alak, így
•
N = 1 ⋅ 2 −10 ⋅ 2 −14 = 2 −24 = 0,000000059604644775390625 1 800116 : ugyanaz, mint az elıbb, csak negatív elıjellel, tehát N = (− 1) ⋅ 2 −10 ⋅ 2 −14 = −2 −24
•
0200 16 : 020016 = 00000010000000002 → 0 000001000000000, vagyis s = 0 , k = 0
•
m = 2 9 , és ennek megfelelıen N = 2 9 ⋅ 2 −10 ⋅ 2 −14 = 2 −15 = 0,000030517578125 . Ez a legkisebb ábrázolható pozitív szám 8200 16 : ez csupán az elıjelben tér el az elızı értéktıl
•
03FF16 :
03FF16 = 00000011111111112 → 0 000001111111111,
10
így
s=0,
k =0
és
és
m = 2 − 1, tehát 10 −10 −14 −10 −14 −14 −24 . A N = 2 − 1 ⋅ 2 ⋅ 2 = 1 − 2 2 = 2 − 2 = 0,000060975551605224609375 legnagyobb nem normalizált szám.
(
)
(
)
FELADATOK
102
(
)
•
83FF16 : N = − 1 − 2 −10 2 −14 . Mint az elıbb, csak negatív elıjellel.
•
0400 16 : 040016 = 00000100000000002 → 0 000010000000000 . Ez a legkisebb pozitív nor-
•
malizált szám, és az értéke N = 1 + 0 ⋅ 2 −10 21−15 = 2 −14 = 0,00006103515625 . 8400 16 : mint az elıbb, de negatív elıjellel
•
1935 16 : 193516 = 00011001001101012 → 0 00110 0100110101, így s = 0 , k = 6 és m = 309 ,
(
(
)
)
és ekkor N = 1 + 309 ⋅ 2 −10 2 6−15 = 1,3017578125 ⋅ 2 −9 = 0,002542495727539064453125 •
C 812 16 : C81216 = 11001000000100102 → 110010 0000010010 . Most
(
s =1,
k = 18
és
)
m = 18 , tehát N = (− 1) 1 + 18 ⋅ 2 −10 218−15 = −1,017578125 ⋅ 2 3 = −8,140625 1
•
7 BFF16 : 7 BFF16 = 01111011111111112 → 0 111101111111111. Az elıjelbit ismét 0, k = 30
•
, és m = 1023 , így N = 1 + 1023 ⋅ 2 −10 2 30 −15 = 1,9990034375 ⋅ 215 = 32735,34454 . Ez a legnagyobb ábrázolható szám 7C 0016 : 7C 0016 = 01111100000000002 → 0 111110000000000 . s = 0 , k = 31 , és m = 0 .
(
• • •
)
Mivel k valamennyi bitje 1, és m = 0 , ezért ez a végtelent ábrázolja, mégpedig a + ∞ -t, mert az elıjelbit 0. FC 0016 : az elıbbihez képest csak az elıjelbitben van különbség, így ez a − ∞ gépi ábrázolása 7C 0 D16 : a kettıvel korábbitól csak abban különbözik, hogy most m ≠ 0 , ezért ez nem szám FC 0 D16 : mint az elıbb, tehát ez is nem szám.
Felhívjuk a figyelmet, hogy a nem normalizált alak esetén más a kitevıben az eltolás értéke, mint a normalizált esetben. A normalizált számnál e = 2 t −1 − 1 , ahol t a karakterisztika kódjában a bináris jegyek száma. Ez a denormalizált számnál, azaz akkor, ha a karakterisztika kódja 0, azt jelent −1 tené, hogy a mantisszát 2 −e = 2 − (2 −1) -gyel, azaz a Példa estén 2 −15 -tel kellene szorozni, míg a fenti példákban e helyett a szorzó értéke 2 −14 . Ez nem elírás. Nézzük ugyanis, hogy mi a kódja 2 − (e −1) -nek és 2 − e -nek. Az elıbbi ábrázolható normalizált alakban, és 2 − (e−1) = 1,0 K 0 ⋅ 21−e következtében a mantissza kódja 0, míg a karakterisztikáé 1 (mert a legmagasabb helyiértékő 1-et nem ábrázoljuk). A második esetben a számot már nem tudjuk normalizált alakban megadni (hiszen az elıbbi szám volt a legkisebb abszolút érték, amelyet normalizált formában lehetett ábrázolni). Most a kitevı kódja 0 lesz, 1 és a mantisszát úgy kell megadni, hogy az értéke és 1 közé essen (az elıbbit beleértve, az utóbbit 2 1 nem). Ilyen módon írva ez a szám 2 − e = ⋅ 2 −e +1 = 0,1 ⋅ 2 0 −(e −1) , vagyis most az eltolás értéke e − 1 . 2 A végtelen illetve a nem szám esetén a számolási szabályok: • •
ha az egyik operandus nem szám, akkor az eredmény is nem szám ha az egyik operandus ∞ , és a másik operandus u, amely nem nem szám, akkor ha matematilag értelmezve van a mővelet a kiterjesztett számkörben, akkor a szerint alakul az eredmény, míg ha a kiterjesztett számkörben sem lehet elvégezni a kijelölt mőveletet, akkor az eredmény nem szám.
A szoftveres lebegıpontos ábrázolás különbözik a fenti szabványtól, és a nagy gépekben alkalmazott gépi ábrázolás sem ilyen általában. Ezekben az esetekben a leggyakoribb, hogy a normalizált szám olyan, hogy a mantisszát a d-alapú számrendszerben írva, ahol N = m ⋅ d t , a d-edespont utáni elsı számjegy különbözik nullától (vagyis ha a szám nem 0, akkor d −1 ≤ m < 1 ), és a mantissza valamennyi jegyét ábrázoljuk, továbbá ha a kitevıt t bit ábrázolja, akkor e = 2 t −1 . A feladatokban az
Számítógépi matematika
103
ilyen ábrázolásra a nem szabványos ábrázolás-sal utalunk, és ilyenkor a példában a kód teljes hossza 16 bit, ebbıl a bal szélsı az elıjelbit, a következı 5 bit az eltolt nullpontú kitevı, és a maradék 10 bit a mantissza. Erre is adunk példát: • •
0000 16 : ez most is a 0 8000 16 : ismét a negatív 0
•
000116 , és d = 2 : k = 0 , tehát N = 1 ⋅ 2 −10 ⋅ 2 0−16 = 2 −26 = 0,0000019073486328125
•
800116 , és d = 16 : = − 1 ⋅ 2 −10 16 0 −16 = −2 −74
•
•
1010 16 , és d = 2 : k = 4 és m = 16 , így N = 16 ⋅ 2 −10 ⋅ 2 4−16 = 2 −18 = 0,000003814697265625 . Ez nem normalizált szám, mert a mantissza legmagasabb helyiértékő bitje 0. 1010 16 , és d = 16 : N = 16 ⋅ 2 −10 ⋅ 16 4 −16 = 2 −54 . Nem normalizált szám, mert a mantissza négy legmagasabb helyiértékő bitje egyaránt 0. 1040 16 , és d = 2 : k = 4 és m = 64 , így N = 64 ⋅ 2 −10 ⋅ 2 4−16 = 2 −16 = 0,0000152587890625 . Ez nem normalizált szám, mert a mantissza legmagasabb helyiértékő bitje 0. 1040 16 1010 16 , és d = 16 : N = 64 ⋅ 2 −10 ⋅ 16 4 −16 = 2 −52 . Ez normalizált szám, mert a mantissza négy legmagasabb helyiértékő bitje 00012 = 116 , vagyis ez a jegy a 16-os számrendszerben nem 0. C 600 16 , és d = 2 : N = − 2 9 ⋅ 2 −10 ⋅ 217 −16 = −1 . Ez normalizált szám.
•
C 600 16
•
7 FFF16
•
FFFF16
• • •
(
)
( ) , és d = 16 : N = −(2 ⋅ 2 ) ⋅ 16 , és d = 2 : N = (2 − 1)2 ⋅ 2 , és d = 16 : N = −(2 − 1)2 ⋅ 16 9
−10
17 −16
−10
10
10
−10
31−16
= −8 . Normalizált szám. = 1023 ⋅ 2 5 = 32736 . Normalizált szám.
31−16
= −1023 ⋅ 2 50 . Ez is normalizált szám.
Mivel a „szoftveres” lebegıpontos számábrázolásnál feltettük, hogy a mantissza valamennyi butjét, tehát a legmagasabb helyiértéken álló, normalizált alakban biztosan 1 értékő bitet is mindig ábrázoljuk, ezért most ugyanaz a kitevıben az eltolás a normalizált és a denormalizált esetben.
FELADATOK
104
A tárgyalt anyaghoz kapcsolódó feladatok 1. Írjon algoritmust, amely az r-alapú számrendszerben megadott egész szám értékét számítja ki. Az eredeti szám je02gyei egy n-mérető tömbben vannak, a legalacsonyabb helyiérték a 0. indexő, és r is paramétere az algoritmusnak. 2.
Adja meg a Horner-módszerrel 4302 6 értékét.
3.
Számítsa ki 0.32064 7 értékét a Horner-módszerrel.
4.
Írja fel 1579-et 7-es számrendszerben; az átalakítást az elıadáson ismertetett módon végezze
5. Írja fel 0.573-at 9-es számrendszerben 6 jegy pontosságig; az átalakítást az elıadáson ismertetett módon végezze. 6.
Írja fel 0.573-at a kettes számrendszerben, ha ez a szám egy mérés eredménye ( lg 2 ≈ 0.3010 ).
7. Alakítsa át 573.0625-et és 573.2451-et a 6-os számrendszerbe majd vissza, és hasonlítsa össze a kapott számot az eredetivel. Magyarázza meg az eredményt. 8. Adja meg 622.43 illetve 7835.43 kódját, ha a számot a 6-os számrendszerben 8 jeggyel reprezentáljuk, amelybıl 3 a törtjegyek száma, majd számítsa ki a kódokhoz tartozó számot. Magyarázza meg az eredményt. 9.
Adja meg 1100101111 101.110001 2 hexadecimális kódját.
10. Adja meg 2301.5002 8 bináris kódját. 11. Alakítsa át 351782 .25419 -et a 27-es számrendszerbe. 12. Adja meg 98 illetve − 98 a. elıjeles abszolút értékes b. komplemens c. eltolt nullpontú kódját 8 bittel, ha a gép egész számokat ábrázol, és c.-ben az eltolás értéke 128. 13. Melyik az az u egész szám, amelynek 8 biten megadott kódja 0, 189, 57, 255 illetve 128, ha a kódolás a. elıjeles abszolút értékes b. komplemens c. eltolt nullpontú, és az eltolás értéke 127 14. Az u és a v egész számok 8-bites kódja 157 és 85. Végezze el a gépi összeadást, ha a kódolás (mind az eredeti adatoké, mind a végeredményé) a. elıjeles abszolút értékes b. komplemens c. eltolt nullpontú, és az eltolás 127.
Számítógépi matematika
105
15. Az u és a v egész szám 8-bites komplemens kódja 157 és 221. Végezze el az összeadást az eredeti számokon, valamint a gépi összeadást, és magyarázza meg az eredményt. 16. Az u egész szám 8-bites kódja 187 illetve 128. Az eredeti szám kiszámítása nélkül adja meg − u kódját, ha a kódolás a. elıjeles abszolútértékes b. komplemens c. eltolt nullpontú a 128-as eltolással. Ahol szükséges, adjon magyarázatot. 17. Két egész szám, u és v kódja 8 biten 13 és 248. Számítsa ki a gépi szorzás eredményét, ha a gép a számokat egészként kezeli, és a szorzat 16 biten keletkezik, amennyiben a kódolás a. elıjeles abszolútértékes b. komplemens 18. Adott két egész szám, 57 és − 63 . Számítsa ki a két szám 8-bites komplemens kódjának 8-bites és 16 bites szorzatát, a 16-bites komplemens kódok 16-bites szorzatát, és hasonlítsa össze az eredményül kapott kódok mint komplemens kódok által reprezentált számokat az eredeti két szám szorzatával. Magyarázza meg az eredményt. 19. Egy gép az elıjel nélküli számokat 8 biten ábrázolja, amelybıl 3 a törtjegyek száma. Az u és v számok kódja 10110111 és 11000101. Határozza meg a gépi szorzás eredményét. 20. Adja meg − 370.12 normalizált alakjának lebegıpontos kódját hexadecimális alakban, ha az alap 16, a normalizálás két egész jegyre történik, és a kódot 16 biten ábrázoljuk: a bal szélsı biten a mantissza elıjelét, a következı 5 biten a kitevı 15-tel eltolt értékét, végül a további 10 biten a mantissza abszolút értékét. A kód kezeli a kitevı-alul- és túlcsordulást. 21. Oldja meg az elızı feladatot, ha a számot a szabvány szerint ábrázoljuk. 22. Egy szám 16-bites lebegıpontos kódja hexadecimális alakban D816 16 . A bal szélsı bit a mantissza elıjele, a következı 5 bit a kitevı eltolt nullpontú kódja, végül a mantissza abszolút értéke következik 10 biten. A lebegıpontos kódban a karakterisztika alapja 16. Állapítsa meg, hogy a fenti kód normalizált alaknak felel-e meg, és ha nem, akkor adja meg a normalizált alak kódját. A kód kezeli a kitevı-alul- és túlcsordulást. 23. Melyik az a szám, amelynek a szabvány szerinti lebegıpontos kódja hexadecimális alakban D816 16 ? 24. Egy gép a lebegıpontos számokat a szabvány szerint tárolja. Az u és v szám kódja DA1616 és 93A 7 16 . Adja meg a két szám különbségének hasonló alakú kódját; a számítást úgy végezze, ahogy a gép is csinálja. A kód kezeli a kitevı-alul- és túlcsordulást. 25. Egy gép a lebegıpontos számokat a szabvány szerint tárolja. Az u és v szám kódja DA1616 és 93A 7 16 . Adja meg a két szám szorzatának hasonló alakú kódját; a számítást úgy végezze, ahogy a gép is csinálja. A kód kezeli a kitevı-alul- és túlcsordulást. 26. Egy gép a lebegıpontos számokat a szabvány szerint tárolja. Az u és v szám kódja 8C1616 és 0C0D 16 . Adja meg a két szám összegének hasonló alakú kódját; a számítást úgy végezze, ahogy a gép is csinálja. A kód kezeli a kitevı-alul- és túlcsordulást. Adjon magyarázatot a megoldáshoz.
FELADATOK
106
27. Egy gép a lebegıpontos számokat a szabvány szerint tárolja. Az u és v szám kódja FA1616 és 740 D 16 . Adja meg a két szám különbségének hasonló alakú kódját; a számítást úgy végezze, ahogy a gép is csinálja. A kód kezeli a kitevı-alul- és túlcsordulást. Adjon magyarázatot az eredményhez. 28. Adja meg − 5674 BCD-kódját hexadecimális alakban, ha a kódot 40 bittel ábrázoljuk, és az elıjelet a legmagasabb helyiérték elıtti bájton adjuk meg. 29. Oldja meg az elızı feladatot azzal az eltéréssel, hogy az elıjelet a legalacsonyabb helyiértéket tartalmazó bájt alsó fél bájtján adjuk meg. 30. Két szám 40-bites BCD-kódja hexadecimális alakban 0003569108BCD és 8000070132BCD. Adja meg az összegük ugyanilyen alakú kódját. 31. Melyik szám BCD-kódja 93278BBCD? 32. Adott az alábbi üzenet: 1101001101 0 2 . Adja meg az üzenet Hamming-kódját. 33. Egy üzenetet Hamming-kóddal küldenek el, és a vétel helyére hexadecimális alakban 6BE 516 érkezik (az üzenet hossza és az elıbbi hexadecimális szám bináris alakja nem feltétlenül azonos hoszszúságú!). Mi lesz a dekódolt üzenet? 34. Az 1101001101 0 2 üzenetet Hamming-kódoljuk, majd elküldjük. Az átvitel során meghibásodik a balról számított 3., 12. és 15. bit. Mi lesz a dekódolt üzenet? És ha a 2., 12. és 15. bit hibásodik meg? És ha a hibák az 1., 2. és 4 pozícióban lépnek fel? 35. Egy 12-bájtos blokkot akarunk egy hiba ellen védeni. Melyik gazdaságosabb, a kétdimenziós paritásellenırzés, vagy ha a teljes blokkot egyetlen szóként (az egyes bájtokat közvetlenül egymás után írva) Hamming-kóddal kódoljuk? 36. Mi a helyzet akkor, ha az elızı, 35-ös feladatban a blokkot rövidített Hamming-kóddal kódoljuk? 37. Egy 8-bájtos blokkot kétdimenziós paritásellenırzı kóddal kódolunk, az egyes bájtokat páratlanra, míg az egyes sávokat párosra kiegészítve, az utolsó, ellenırzı karakter ellenırzıbitjét „függılegesen” számítva. Kiolvasáskor a következı sorozatot kapjuk: 139 16 , 07 A 16 , 1F016 , 11B16 , 07 E 16 , 00116 , 10316 , 1E116 és 13D 16 (a paritásbit közvetlenül a jobbra igazított adatbájt bal szélén áll). Állapítsa meg, hogy történt-e hiba, ha igen, akkor javítható-e, és ha igen, akkor javítson, továbbá adja meg a dekódolt blokkot (feltesszük, hogy az utolsó karakter hibátlan). Mi a helyzet akkor, ha a) b) c) d) e) f) g) h) i) j)
07 A 16 07 E 16 07 A 16 07 E 16 07 A 16 07 A 16 07 A 16 07 A 16 07 A 16 07 E 16
helyett 07216 helyett 03E 16 helyett 07 B16 helyett 01E16 helyett 07216 és 10316 helyett 10B16 helyett 07216 és 07 E 16 helyett 03E 16 helyett 07 B16 és 07 E 16 helyett 03E 16 helyett 07 B16 és 10316 helyett 102 16 helyett 07 B16 és 10316 helyett 10116 helyett 03E 16 és 07 A 16 helyett 03216
érkezik, és feltesszük, hogy a hibátlan adatblokk az elıbbi javítással kapott blokk?
Számítógépi matematika
107
38. Adja meg az N szám 8-bites komplemens, 127-tel eltolt nullpontú és 128-cal eltolt nullpontú kódját, ha az elıjeles abszolút értékes kód 0016 , 1A 16 , 8016 illetve 9A 16 . A számítást közvetlenül a kódokkal végezze. 39. Adja meg az N szám 8-bites elıjeles abszolút értékes illetve komplemens kódját, ha a 128-cal eltolt nullpontú kód 0016 , 1A 16 , 8016 illetve 9A16 . A számítást közvetlenül a kódokkal végezze. 40. Adja meg az N szám 8-bites elıjeles abszolút értékes illetve komplemens kódját, ha a 127-tel eltolt nullpontú kód 0016 , 1A 16 , 7 F16 , 8016 , 9A16 illetve FF16 . A számítást közvetlenül a kódokkal végezze. 41. Adja meg N 8-bites elıjeles abszolút értékes, 128-cal illetve 127-tel eltolt nullpontú kódját, ha a komplemens kód 0016 , 1A 16 , 8016 illetve 9A16 . A számítást közvetlenül a kódokkal végezze. 42. Egy gépben a lebegıpontos számokat 32 biten ábrázolják: a bal szélsı bit a mantissza elıjele, s, a következı 8 bit, e, a karakterisztika eltolt nullpontú kódja, majd 23 biten m′ , a mantissza abszolút értéke következik, ahol nem ábrázoljuk a legmagasabb helyiértékő bitet, amennyiben a szám normalizált. A normalizált alakban 1 ≤ e ≤ 254 , és a szám egy egész jegyre normalizált; e = 0 jelzi a denormalizált alakot, míg ha e = 255 , akkor m′ = 0 esetén a szám végtelen, ellenkezı esetben a kód nem számot ábrázol. Normalizált esetben e = k + 127 , míg ha a szám denormalizált, akkor e = k + 126 , ahol k a lebegıpontos szám kitevıje. Mi lesz ebben a gépben − 48 , 24 ⋅ 2 −138 , 24 ⋅ 2 −153 , 24 ⋅ 2 −154 illetve 24 ⋅ 2125 lebegıpontos kódja? 43. Az alábbiak közül melyik igaz: a. b. c. d. e. f. g.
A⊕ B = A⊕ B A⊕ B = A⊕ B A⊕ B = A⊕ B A(B ⊕ C ) = ( AB ) ⊕ ( AC ) A ⊕ (BC ) = ( A ⊕ B )( A ⊕ C ) A + (B ⊕ C ) = ( A + B ) ⊕ ( A + C ) A ⊕ (B + C ) = ( A ⊕ B ) + ( A ⊕ C )
h. A + B ⊕ C = ( A + B ) ⊕ ( A + C ) ahol AB A és B, A + B A vagy B és A ⊕ B az A és B kizáró vagy kapcsolata.
Egyéb, a számítógépek felépítéséhez tartozó feladatok 44. Egy adatátviteli hálózat 8 különbözı jellel viszi át az üzenetet, az átvitel sebessége 3200 Baud . Mekkora az átviteli sebesség bit s -ban, ha az egyes jelek elıfordulása azonos valószínőségő? 45. Mekkora videomemóriára van szükség, ha a monitor 1024 × 768 pontos felbontású, és 65536 színt jelenít meg? Mekkora a szükséges kapacitás akkor, ha a rendelkezésre álló alkatrészek 1 MB osak? ( MB a megabájt rövidítése.) 46. Mekkora memória kell egy 210 × 297 mm 2 -es (A4-es mérető) fekete-fehér rajz pontonkénti tárolásához, ha a rajz felbontása mindkét irányban 600 dpi ?
FELADATOK
108
47. Egy gép memóriája 32 bájtos, az utasítások egy címesek és 8 bitesek, amelybıl a bal szélsı 3 bit a mőveleti kód, és a következı 5 bit az adat címe a memóriában. A gép az összeadást komplemens kódban végzi. Az egyes utasítások és a hozzájuk tartozó mőveleti kód: 0: 1: 2: 3: 4: 5: 6: 7:
L S A J JZ JN C H
M M M M M M X X
ahol M egy memóriacím, X tetszıleges érték, L a memóriából az akkumulátorba, S az akkumulátorból a memóriába való adattranszfer, A összeadás, J feltétel nélküli, JZ a nulla, JN a negatív akkumulátor esetén való ugrás, C az akkumulátor tartalmának komplementálása, míg H a megállító utasítás. A PC jelenlegi tartalma 5, az akkumulátoré 1516 , a memóriában a 0-s címtıl sorban 3A 16 , 1116 , 17 16 , C316 , 5A 16 , C016 , 5116 , A516 , 5015 , 3216 , 0616 , 1616 , D7 16 , F116 , 2316 , 2516 , 0116 , 1016 , DC 16 , 2016 , 2116 , 2216 , 2316 , 2416 , 2516 , 2616 , 27 16 , 2816 , 2916 , 3016 , 3116 , 3216 áll, és a gép éppen befejezett egy utasítást. Adja meg a PC, az AC és az SR tartalmát a soron következı 3. utasítás végrehajtása után, ha SR-ben CF, OF, ZF, SF rendre az átvitelt, a túlcsordulást, a nullát és az elıjelet jelzi. 48. Egy 3.5 collos hajlékony lemez kapacitása 1.44 MB , a sávok száma 80, és percenként 360 fordulatot tesz meg. Mekkora az átviteli sebesség, ha valamennyi sávon azonos mennyiségő adat helyezkedik el? 49. Egy mágnesszalag, amelyen keresztirányban egy bájt van, 6 m s -os sebességgel mozog, és a felírási sőrőség 800 bpi . Mekkora az átviteli sebesség? 50. Egy teljesen asszociatív cache-tár egy-egy sora 16 bájtnyi adatot tartalmaz. Mekkora egy sor bitben kifejezett hossza, ha jelezzük, történt-e módosítás az adott soron, és az operatív memória kapacitása 1 MB ? 51. Egy teljesen asszociatív cache-tár egy-egy sora 16 bájtnyi adatot tárol, és jelzi, hogy történt-e változás egy adott sorban. Mekkora az operatív memória kapacitása, ha a cache-tár egy-egy sora 150 bites? 52. Legyen egy adat: 11010001 2 2. Adja meg az íróáram változását, ha a felírási mód a. NRZI b. FM c. MFM 53. Mi volt a felírt információ, ha kiolvasáskor az alábbi jelsorozatot kapjuk: a. +U
−U
Számítógépi matematika
109
b. +U
−U
c. +U
1
1
0
1
0
0
0
1
−U
54. Adja meg azt az információt, amelyhez tartozó íróáram az alábbi: a.
+I
−I
b.
+I
−I
c.
+I
−I
55. Egy gép utasítása 32 bites, ebbıl a bal szélsı 8 bit az utasításkód, a következı 4 bit az elsı operandust tartalmazó regiszter címe, utána 4 bit az aktuális indexregiszter, majd újabb 4 bit az aktuális bázisregiszter címe, végül az utolsó 12 bit tartalmazza a relatív címet. Adja meg az elsı operandust és a második operandus címét, ha az aktuális utasítás 8230 A 0B616 , és a 16 regiszter tartalma sorrendben egymás után 76CA103316 , 88002412 16 , 0000 ADAF16 , DC 4E 23A 216 , 968B3CD 416 , FB4A346 A 16 , 5A 621BC416 , 7252011116 , 00000000 16 , FFFFFFFF16 , 030 A 02 BA 16 , 3CCD 2AA 416 , 47142 A 4116 , 5825C34A 16 , ADACAA 2016 , és 8316 BF2E 16 . 56. Egy gép utasításai 12 bitesek, ebbıl a 3 bal szélsı bit az utasításkód, a következı bit mutatja, hogy direkt vagy indirekt címzést alkalmazunk-e: 0 a direkt címet jelzi, majd egy bit mutatja, hogy
110
FELADATOK
indexelünk-e vagy sem, mégpedig ennek a bitnek az 1 értéke esetén történik indexelés, és a fennmaradó 7 bit a címrész. Az éppen feldolgozandó utasítás 5675 8 , az indexregiszter tartalma 0010 8 . Mi lesz az adat címe, ha a memóriában a 70 8 -as címtıl kezdve 1100 8 , 2020 8 , 6452 8 , 4560 8 , 2202 8 , 7240 8 , 6624 8 , 3302 8 , 5534 8 , 5502 8 , 7024 8 , 3344 8 , 3310 8 , 4440 8 , 3434 8 és 2200 8 áll? 57. Egy gép lapcímzést alkalmaz, egy lap mérete 4 kB , továbbá a laptábla a memória 100 16 -os címén kezdıdik, és egy-egy lapra vonatkozó bejegyzés 16 bit, amelybıl az elsı 14 az aktuális fizikai lapcím, míg a fennmaradó két bit közül az elsı az érvényességi bit, a második a lap változását mutató bit. Az utasítások utolsó 20 bitje vonatkozik a címre, ebbıl az elsı 4 bit az indexregiszter, a második 4 bit a bázisregiszter sorszáma, a fennmaradó 12 bit az eltolás értéke. Az éppen kiolvasott utasítás sorban 76CA103316 , 88002412 16 , 0000 ADAF16 , CA 45A 20616 , a 16 regiszter tartalma DC 4E 23A 216 , 968B3CD 416 , FB4A346 A 16 , 5A 621BC416 , 7252011116 , 00000000 16 , FFFFFFFF16 , 04B622 BA 16 , 3CCD 2AA 416 , 47142 A 4116 , 5825C34A 16 , ADACAA 2016 , és 8316 BF2E 16 , és a memóriában a 100 16 -as címtıl kezdve sorban 00120344 16 , 12023310 16 , CCA 2132 B16 , CCA14560 16 , 2203ACAD16 , 441300 A016 , 98235546 16 és ACA 23204 16 áll. Adja meg az operandus fizikai címét. 58. Egy gép szegmenscímzést alkalmaz, a szegmenstábla a memória 100 16 -as címén kezdıdik, és egy-egy szegmensre vonatkozó bejegyzés 32 bit, amelybıl az elsı 4 bit nem számít, a következı 26 bit a szegmens kezdıcíme, míg a fennmaradó két bit közül az elsı az érvényességi bit, a második a szegmens változását mutató bit. Az utasítások utolsó 20 bitje vonatkozik a címre, ebbıl az elsı 4 bit az indexregiszter, a második 4 bit a bázisregiszter sorszáma, a fennmaradó 12 bit az eltolás értéke. A bázis- és indexregiszterrel kiszámolt cím alsó 12 bitje adja a szegmensen belüli eltolás értékét. Az éppen kiolvasott utasítás CA 45A 20616 , a 16 regiszter tartalma sorban 76CA103316 , 88002412 16 , 0000 ADAF16 , DC 4E 23A 216 , 968B3CD 416 , FB4A346 A 16 , 5A 621BC416 , 7252011116 , 00000000 16 , FFFFFFFF16 , 04B622 BA 16 , 3CCD 2AA 416 , 47142 A 4116 , 5825C34A 16 , ADACAA 2016 , és végül 8316 BF2E 16 , és a memóriában a 100 16 -as címtıl kezdve sorban egymás után 00120344 16 , 12023310 16 , CCA 2132 B16 , CCA14560 16 , 2203ACAD16 , 024A346 A 16 , 98235546 16 és utoljára ACA 23204 16 áll. Adja meg az operandus fizikai címét. 59. Egy gép lapcímzést alkalmaz, egy lap mérete 4 kB , továbbá a laptábla a memória 100 16 -os címén kezdıdik, és egy-egy lapra vonatkozó bejegyzés 16 bit, amelybıl az elsı 14 az aktuális fizikai lapcím, míg a fennmaradó két bit közül az elsı az érvényességi bit, a második a lap változását mutató bit. Az utasítások utolsó 20 bitje vonatkozik a címre, ebbıl az elsı 4 bit az indexregiszter, a második 4 bit a bázisregiszter sorszáma, a fennmaradó 12 bit az eltolás értéke. Az éppen kiolvasott utasítás CA 45A 20616 , a 16 regiszter tartalma sorban egymás után 76CA103316 , 88002412 16 , 0000 ADAF16 , DC 4E 23A 216 , 968B3CD 416 , FB4A346 A 16 , 5A 621BC416 , 7252011116 , 00000000 16 , FFFFFFFF16 , 04B622 BA 16 , 3CCD 2AA 416 , 47142 A 4116 , 5825C34A 16 , ADACAA 2016 , és 8316 BF2E 16 , és a memóriában a 100 16 -as címtıl kezdve sorban 00120344 16 , 12023310 16 , CCA 2132 C16 , CCA14560 16 , 2203ACAD16 , 441300 A016 , 98235546 16 és ACA 23204 16 áll. Adja meg az operandus fizikai címét. 60. Egy gép szegmenscímzést alkalmaz, a szegmenstábla a memória 100 16 -as címén kezdıdik, és egy-egy szegmensre vonatkozó bejegyzés 32 bit, amelybıl az elsı 4 bit nem számít, a következı 26 bit a szegmens kezdıcíme, míg a fennmaradó két bit közül az elsı az érvényességi bit, a második a szegmens változását mutató bit. Az utasítások utolsó 20 bitje vonatkozik a címre, ebbıl az elsı 4 bit az indexregiszter, a második 4 bit a bázisregiszter sorszáma, a fennmaradó 12 bit az eltolás értéke. A bázis- és indexregiszterrel kiszámolt cím alsó 12 bitje adja a szegmensen belüli eltolás értékét. Az éppen kiolvasott utasítás CA 45A 20616 , a 16 regiszter tartalma sorban 76CA103316 , 88002412 16 , 0000 ADAF16 , DC 4E 23A 216 , 968B3CD 416 , FB4A346 A 16 , 5A 621BC416 , 7252011116 , 00000000 16 ,
Számítógépi matematika
111
FFFFFFFF16 , 04B622 BA 16 , 3CCD 2AA 416 , 47142 A 4116 , 5825C34A 16 , ADACAA 2016 , és 8316 BF2E 16 , és a memóriában a 100 16 -as címtıl kezdve sorban 00120344 16 , 12023310 16 , CCA 2132 B16 , CCA14560 16 , 2203ACAD16 , 041300 A016 , 98235546 16 és ACA 23204 16 áll. Adja meg az operandus fizikai címét.
FELADATOK
112
Megoldások 1. horner(r, A, s) [ 2 ≤ r ∈ N , n ∈ N , A[0..n − 1] , r > A[i ]∈ N 0 ] s = A[n − 1] ciklus i = n − 2 -tıl 0-ig − 1 -esével s = r ∗ s + A[i ] ciklus vége eljárás vége. (Az algoritmusnál feltételeztük, hogy a ciklusban a ciklusváltozó vizsgálata a ciklus elején történik.) 2.
A Horner-módszerrel 4302 6 = ((4 ⋅ 6 + 3)6 + 0 )6 + 2 = (27 ⋅ 6 )6 + 2 = 162 ⋅ 6 + 2 = 974 10 .
3.
A törtekre vonatkozó Horner-módszerrel 4 +6 7 +0 46 7 +2 +2 732 7 + 3 343 +3 +3 7935 7 7 ; 0.32064 7 = = = 2401 = 7 7 7 16807
a másik lehetıség, hogy kiszámítjuk 32064 7 -et, és elosztjuk 7 ötödik hatványával: 0.32064 7 =
(((3 ⋅ 7 + 2)7 + 0)7 + 6)7 + 4 = 7
5
7935 . 16807
Tizedestörtként való felíráshoz elıször meghatározzuk, hogy hány jegyre számoljunk. Az eredeti szám pontossága 7 −5 . Legyen 10 − (k −1) > 7 −5 ≥ 10 − k , ahol k ∈ Z . Innen k − 1 < 5 lg 7 ≤ k , és k = 5 lg 7 = 5 , tehát a törtet 5 tizedesjegyre számoljuk, így 0.47212 10 ≤ 0.32064 7 < 0.4721310 . 4. 1579 225 4 32 1 4 4
1579 1579 tehát 1579 10 = 4414 7 (például a 2. sorban 225 = , és 4 = (1579 mod 7 ) = 1579 − 7 ⋅ ). 7 7 Ellenırzés: ((4 ⋅ 7 + 4 ) ⋅ 7 + 1) ⋅ 7 + 4 = (32 ⋅ 7 + 1) ⋅ 7 + 4 = 225 ⋅ 7 + 4 = 1579 . 5. 0 5 1 3 6 4 0
573 157 413 717 453 077 693
Számítógépi matematika
azaz 0.57310 = 0.513640 K9 . Ellenırzés:
113
(((5 ⋅ 9 + 1) ⋅ 9 + 3) ⋅ 9 + 6) ⋅ 9 + 4 = 33835 = 0.5729K , ugyan95
59049 304516 akkor 0.5136419 = = 0.5730005K10 , vagyis 0.513640 9 ≤ 0.57310 < 0.5136419 . 531441
(Például a második sorban a vonaltól balra 5 = 9 ⋅ 0.573 , és jobbra 9 ⋅ 0.573 − 9 ⋅ 0.573 áll.)
3 2 k ≤ 10 −3 < 2 k +1 -bıl − 3 log 2 10 − 1 < k ≤ −3 log 2 10 , vagyis k = − 3 log 2 10 = − = −10 , lg 2 tehát binárisan 10 jegyre írjuk fel a számot:
6.
0 1 0 0 1 0 0 1 0 1 0
573 146 292 584 168 336 672 344 688 376 752
azaz 0.57310 = 0.1001001010 K 2 . Ellenırzés:
((((((((1 ⋅ 0,5 + 0) ⋅ 0,5 + 1) ⋅ 0,5 + 0) ⋅ 0,5 + 0) ⋅ 0,5 + 1) ⋅ 0,5 + 0) ⋅ 0,5 + 0) ⋅ 0,5 + 1) ⋅ 0,5 = = 0.5722 K10 ≤ 0.57310 < 0.5732 K10 =
= (((((((((1 ⋅ 0,5 + 1) ⋅ 0,5 + 0 ) ⋅ 0,5 + 1) ⋅ 0,5 + 0 ) ⋅ 0,5 + 0 ) ⋅ 0,5 + 1) ⋅ 0,5 + 0 ) ⋅ 0,5 + 0 ) ⋅ 0,5 + 1) ⋅ 0,5 7.
Külön alakítjuk át az egész- és törtrészt. k = 4 log 6 10 = 6 , ezért a törtet 6 jegyre számítjuk. 573 95 3 15 5 23
0 0625 0 375 2 25 15 30 0 0
0 2451 1 4706 2 8236 4 9416 5 6496 3 8976 5 3856
vagyis 573.062510 = 2353.021300 6 és 573.245110 = 2353 .124535 K6 . k = 6 lg 6 = 5 , tehát a visszaalakításnál 5 törtjegyre végezzük a konvertálást: 2353.021300 6 =
((((((2 ⋅ 6 + 3)6 + 5)6 + 3)6 + 0)6 + 2)6 + 1)6 + 3 = 742689 = 573.06250 64
2353.124535 6 =
1296
((((((((2 ⋅ 6 + 3)6 + 5)6 + 3)6 + 1)6 + 2)6 + 4)6 + 5)6 + 3)6 + 5
26745323 = = 573.24509 K10 46656
66
.
10
FELADATOK
114
Az elsı megállapítás, hogy 573.062510 törtrésze véges hatodos tört, vagyis az átalakítás után kapott szám megegyezik az eredetivel, míg a másik szám esetén a 6. jegy meghatározása után még további értékes jegyek következnének, ezért a 6 törtjegyre számított érték kisebb az eredeti számnál. 625 54 1 Az eltérı viselkedés oka, hogy 0.0625 = = 4 4 = 4 , és a nevezı minden prímtényezıje (je10000 2 5 2 lesen az egyetlen 2) osztója az új alapszámnak, a 6-nak, ugyanakkor ez nem igaz 2451 2451 0.2451 = = -re (2451 nem osztható sem 2-vel, sem 5-tel, így nem lehet egyszerősíteni). 10000 2 4 5 4 Másodikként azt látjuk, hogy míg az eredeti számban a tizedes jegyek száma 4, addig visszaalakításkor 5 jegyre kellett számolnunk. Ennek az az oka, hogy az elsı konvertálás után kapott szám utolsó helyiértékén az 1 határozottan kisebb értéket képvisel, mint az eredeti számban, és a visszaalakításkor ennél a kisebb értéknél kisebb, vagy vele egyenlı kell, hogy legyen a legalacsonyabb helyiérték által reprezentált szám. Végül azt látjuk, hogy az elsı szám a visszaalakításkor is véges jegyő tört lesz, és értéke azonos az eredeti értékkel, míg a második szám átalakítása most is folytatódhatna, és így a visszaalakításkor ismét csonkoltunk, vagyis csökkentettük a szám értékét, tehát a visszaalakított szám kisebb az eredetinél. Az elsı eset nyilvánvaló: ha egy véges hosszúságú r-edes tört véges hosszúságú az s-alapú számrendszerben, akkor átalakításkor a pontos értékét, vagyis az eredeti számot kapjuk, csupán más számrendszerben felírva, és akkor természetes, hogy visszaalakításkor visszajutunk az eredeti számhoz. Az is nyilvánvaló, hogy a második esetben az eredetinél kisebb számot kapunk, hiszen mindkét átalakításnál értékes jegyeket veszítettünk, azaz csökkent a szám. 8. 622 103 4 17 1 25 02 00
7835 1305 5 217 3 36 1 60 10
0 43 2 58 3 48 2 88
vagyis ϕ (622.43) = 02514232 = 2514232 és ϕ (7853 .43) = 00135232 = 135232 . Most meghatározzuk a kódokhoz tartozó számokat: 2
5 2
6 1 6
1 17 3 1
4 103 5 9
2 622 2 59
3 356
3 3734 2 2139
(például az elsı esetnél 103 = 6 ⋅ 17 + 1 ), így az elsı kódhoz tartozó szám
2 22407
134444
12836 134444 = 622.425 , a máso63
12836 = 59.425 . Látjuk, hogy a törtrész különbözik az eredeti szám törtrészétıl, amely 63 az átalakításkor elveszett nullától különbözı törtjegyek következménye. Az elsı szám egészrésze megegyezik az eredeti szám egészrészével, ám a másodiké szignifikánsan különbözik, aminek az oka az, hogy míg az elsı esetben elegendı az egészrészhez rendelkezésre álló 5 jegy, addig a második szám esetében ez nem igaz.
dikhoz pedig
9.
1100101111 101.110001 2 = 0001 1001 0111 1101 .1100 0100 2 = 197 D.C416
10. 2301 .5002 8 = 010 011 000 001.101 000 000 010 2 = 1001100000 1.1010000000 12
Számítógépi matematika
115
11. 9 = 3 2 és 27 = 33 , ezért elıbb átalakítjuk a számot a 3-as számrendszerbe, majd innen a 27-esbe. Ez utóbbinál szükségünk van 27 szimbólumra, ezek 0-tól 9-ig a számjegyek, majd innen sorban egymás után az angol ábécé nagybetői következnek, vagyis A: B: C: D: E: F: G: H:
10 11 12 13 14 15 16 17
I: 18 J: 19 K: 20 L: 21 M: 22 N: 23 O: 24 P: 25 Q: 26 351782.25419 = 10 12 01 21 22 02.02 12 11 013 =
= 101 201 212 202.021 211 010 3 = 10 19 23 20.7 22 3 27 = AJNK.7 M 3 27 12. 98 a. 01100010 b. 01100010 c. 11100010 13.
− 98 11100010 10011110 00011110
(
)
(
)
(
)
a. 0, − 189 − 2 7 = −61 , 57, − 255 − 2 7 = −127 , − 128 − 2 7 = −0 8
8
8
b. 0, 189 − 2 = −67 , 57, 255 − 2 = −1 , 128 − 2 = −128 c. 0 − 127 = −127 , 189 − 127 = 62 , 57 − 127 = −70 , 255 − 127 = 128 , 128 − 127 = 1 14.
(
)
a. 85 − 157 − 2 7 = 56
(
)
b. 157 + 85 mod 2 8 = 242 c. 157 + 85 − 127 = 115 15.
(157 − 2 ) + (221 − 2 ) = −134 8
(157 + 221 mod 2 ) = 122
8
8
122 a + 122 komplemens kódja, vagyis nem a helyes eredmény kódja; túlcsordulás történt, ugyanis az összeg kisebb a megengedett minimális értéknél, − 128 -nál. 16. a. 187 − 2 7 = 59 b. 2 8 − 187 = 69
128 − 2 7 = 0 2 8 − 128 = 128 → CF = 1
128 a − 128 komplemens kódja, tehát most − u = 128 , de 128 8 bittel nem adható meg komplemens kódban. Ezt jelzi a túlcsordulásbit. c. 128 + (− (187 − 128 )) = 69
128 + (− (128 − 128 )) = 128
A c.-beli eredményt másként is megkaphatjuk:
FELADATOK
116 2 ⋅ 128 − 187 = 69
2 ⋅ 128 − 128 = 128
ugyanis ϕ en (− α ) = K + (− α ) = K + (− (ϕ en (α ) − K )) = 2 K − ϕ en (α ) 17.
(
)
a. 13 ⋅ 248 − 2 7 + 215 = 34328 b. 2
16
(
)
8
− 13 ⋅ 2 − 248 = 65432
18. 57 ⋅ (− 63) = −3591
ϕ k(8 ) (57 ) = 57 ϕ k(16 ) (57 ) = 57 ϕ k(8 ) (− 63) = 2 8 − 63 = 256 − 63 = 193 ϕ k(16 ) (− 63) = 216 − 63 = 65536 − 63 = 65473 57 ⋅ 193 = 11001
(ϕ ( ) (57) ⋅ ϕ ( ) (− 63) mod 2 ) = (57 ⋅ 193 mod 2 ) = 249 = ϕ ( ) (− 7) (ϕ ( ) (57) ⋅ ϕ ( ) (− 63) mod 2 ) = (57 ⋅ 193 mod 2 ) = 11001 = ϕ ( ) (11001) (ϕ ( ) (57) ⋅ ϕ ( ) (− 63) mod 2 ) = (57 ⋅ 65473 mod 2 ) = 61945 = ϕ ( ) (− 3591) 8 k 8 k 16 k
8 k 8 k 16 k
8
8
16
16
8 k
16
16 k
16
16 k
n-bites komplemens kódok 2n -bites szorzata csak speciális esetben adja a helyes eredmény 2n bites kódját, nevezetesen pontosan akkor, ha az egyik tényezı 0, vagy mindkét tényezı pozitív, vagy mindkét tényezı a legnagyobb abszolút értékő ábrázolható szám, − 2 n −1 . Ugyanakkor m-bites komplemens kódok m-bites szorzata a helyes eredmény m-bites komplemens kódja, feltéve, hogy a helyes eredmény nem esik kívül az m bittel komplemens kódban ábrázolható számtartományon, azaz benne van a − 2 m −1..2 m −1 intervallum egészeinek halmazában, amely feltétel m = 16 -nál a jelen esetben teljesül, míg m = 8 -nál nem.
[
)
19. 10110.111×11000.101 1011 0111 1011 0111 10 110111 100011 0011.010011 Ebbıl a gép 8 bitet tart meg, amelybıl 3 a törtjegyek száma, tehát a szorzás eredménye 10011010. 20. − 370.1210 = −172.1E K16 = −17.21E K16 ⋅ 161 ⇒ 110000 0001011100 =ˆ C05C16 . Az elsı bit 1, mert a szám negatív. A következı 5 biten 15 + 1 -et adtuk meg, mert a kitevı 1, végül a maradék 10 bit 1721E K16 bináris alakjának felsı 10 bitje. 21. − 172.1E K16 = −101110010.00011110 K2 = −1.0111001000011110 K2 ⋅ 2 8 , és a fenti szabályok figyelembevételével a kód 110111 0111001000 =ˆ 1101110111001000 2 . Most ismét az elsı bit a szám elıjelét mutatja, a következı 5 bit 15 + 8 bináris alakban, majd a szám mantisszáját ábrázoltuk úgy, hogy a legmagasabb helyiértékő bitet elhagytuk, az ugyanis biztosan 1, és ábrázoltuk az ez után következı 10 bitet.
Számítógépi matematika
117
22. D81616 = 1101100000010110 2 =ˆ 110110 0000010110 , és itt 0000010110 képviseli a mantisszát. A szám akkor normalizált, ha a d-alapú számrendszerben felírva, ahol d a kitevı alapszáma, a legmagasabb helyiértéken álló szám nem nulla. Most d = 16 , vagyis a szám akkor normalizált, ha a mantiszsza bináris felírásában a felsı 4 bit közül legalább egy nem nulla. Ez a feltétel most nem igaz. Normalizált alakot ebbıl úgy kapunk, ha a mantisszát megszorozzuk 16-tal, ami 4 bittel való balra léptetést jelent (és persze a felesleges nullák levágását), és a kitevıt eggyel csökkentjük. Az eredmény 110101 0101100000 = 1101010101100000 2 = D56016 lesz. 23. D81616 =ˆ 110110 0000010110 ⇒ −1.00000101102 ⋅ 2
22−15
= −10000010.110 2 = −130.7510
24. DA1616 =ˆ 110110 1000010110 =ˆ −1.1000010110 ⋅ 2 22 −15 93A716 =ˆ 1 00100 1110100111 =ˆ −1.1110100111 ⋅ 2 4 −15 = −0.0000000000 ⋅ 2 22 −15
így u − v = u . 25. 1.1110100111·1.1000010110 11110100111 11110100111 11110100111 11110100111 10.1110100100100101101
22 + 4 − 15 = 11 (a kitevı 15-tel eltolt értéke)
A bal szélsı 1 a Carry-be kerül, és a törtrészbıl csak 10 bit fér el a mantissza helyén, vagyis a mantisszákkal végzett mőveletbıl 0.1110100100-t és C = 1 -et kapunk. Mivel a Carry-bit 1, a mantiszsza 1 jeggyel túlcsordult, ezért elléptetjük egy hellyel jobbra, és a törtrészbıl ismét csak a 10 felsı bitet tartjuk meg, továbbá a kitevıt eggyel növeljük, végül figyelembe vesszük, hogy két negatív szám szorzata pozitív, így az elıjelbit 0. Elhagyva még a mantissza egész részét kapjuk a végeredményt: 0 01100 0111010010 =ˆ 31D 216 . 26. 8C1616 =ˆ 1 00011 0000010110 =ˆ −1.0000010110 ⋅ 2 3−15 0C0D16 =ˆ 0 00011 0000001101 =ˆ 1.000001101 ⋅ 2 3−15 u + v = −0.0000001001 ⋅ 2 3−15 = −0.0001001000 ⋅ 2 0 −15 ⇒ 1 00000 0001001000 =ˆ 804816 .
Az eredményt nem lehet normalizálni, így normalizálatlan értékét ábrázoljuk. 27. FA1616 =ˆ 111110 1000010110 =ˆ −1.1000010110 ⋅ 2 30 −15 740D16 =ˆ 0 11101 0000001101 =ˆ −1.0000001101 ⋅ 2 29−15 = 0.1000000110 ⋅ 2 30 −15 u − v = −10.0000011100 ⋅ 2 30 −15 = −1.0000001110 ⋅ 2 31−15 ⇒ 111111 0000000000 =ˆ FC0016
mert kitevıtúlcsordulás lépett fel. 28. 8000005674 BCD
FELADATOK
118 29. 000005674 B BCD
30. A legalsó félbájton álló számok értéke kisebb, mint 10, így ez nem az elıjel, vagyis az elıjelet a legfelsı bájt mutatja, és a két szám 3569108 illetve − 70132 , így az eredmény 0003498976 BCD . 31. A legalsó félbájt értéke nagyobb 9-nél, így ez jelenti az elıjelet, és a szám − 93278 . 32. A kód 15-bites, és balról jobbra 1-tıl 15-ig számozva a biteket, a 2-hatványnak megfelelı pozíciókba helyezzük a négy paritásbitet. p 0 az 1., p1 a 2., p 2 a 4. és p 3 a 8. indexő helyre kerül, míg a többi helyen az eredeti sorrendben lesznek az üzenetbitek. Ekkor a kódot úgy határozzuk meg, hogy
0 0 1 0 1 0 1 1 0 1 1 0 0 1 1 0 p 0 + p1 + 1 ⋅ + p 2 + 1 ⋅ + 0 ⋅ + 1 ⋅ + p 3 + 0 0 0 1 1 1 1 0 1 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 1 0 0 1 1 + 0 ⋅ + 0 ⋅ + 1⋅ + 1⋅ + 0 ⋅ + 1⋅ + 0 ⋅ = 0 0 0 1 1 1 1 1 1 1 1 1 1 1 p0 1 1 1 1 0 0 p0 0 0 p 1 0 1 1 0 1 p 0 0 = 1+ + + + + + = 1+ = p p 0 1 1 0 1 1 0 0 2 2 p 0 0 0 1 1 1 p 1 0 3 3 po 0 p 0 legyen. Innen 1 = , és beillesztve a paritásbiteket az üzenetbe a megfelelı helyeken kapjuk a p2 0 p 1 3 kódot: 0010101000 11010 2 . 33. 6BE516 = 0110101111 100101 2 . Mivel a bináris alakban a 2. és a 16. bit értéke 1, ezért az üzenet legalább 15 bites. A Hamming-kód hossza 2 r − 1 , ahol r pozitív egész szám, így a vett szó 1101011111 00101 2 . Kiszámítjuk a szindrómát: 1 0 1 0 1 0 1 0 0 1 1 0 0 1 1 0 1⋅ + 1⋅ + 0 ⋅ + 1⋅ + 0 ⋅ + 1⋅ + 1⋅ + 1⋅ + 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 1 0 1 1 0 0 1 1 + 1⋅ + 1⋅ + 0 ⋅ + 0 ⋅ + 1⋅ + 0 ⋅ + 1⋅ = 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 0 1 0 1 1 1 0 1 0 1 1 0 0 1 0 1 1 = + + + + + + + + + = 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 1 1
Számítógépi matematika
119
amibıl arra következtetünk, hogy a 15. bit a hibás. Ezt a bitet az ellentettjére változtatva és elhagyva a paritásbiteket kapjuk a dekódolt üzenetet: 0011110010 0 2 = 1E 416 . 34. 1101001101 0 2 kódja 0010101100 11010 2 . Ha ebben a megadott bitek meghibásodnak, akkor a 0 0 vétel helyére 0000101100 10011 2 érkezik. Ennek a szónak a szindrómája , tehát nem vesszük 0 0 észre a hibát, így egyszerően elhagyjuk a paritásbiteket, és kapjuk a dekódolt üzenetet: 0101001001 12 . 1 0 A második esetben a beérkezett szó 0110101100 10011 2 , a szindróma , úgy véljük, hogy az 0 0 elsı bit a hibás, ezért ezt megfordítjuk, így az 1110101100 10011 2 szót kapjuk, és ismét elhagyva a paritásbiteket kapjuk az 1101001001 12 szót. 1 1 A harmadik beérkezett szó 1111101100 11010 2 , és ennek a szindrómája , a 7. bitet módosít1 0 juk, és utána elhagyjuk a paritásbiteket, így a dekódolás eredménye 1100001101 0 2 . Érdemes ennél az utolsó esetnél megfigyelni, hogy a kódszóban az átvitel során csak a paritásbitek sérültek, vagyis az eredeti üzenet bitjei hibátlanul érkeznek a vétel helyére, ám a szindróma alapján egy hibátlan bitet „javítunk”, és így dekódolás után nem az eredeti üzenetet kapjuk. 35. 12 × 8 = 96 , és 2 6 − 1 − 6 = 56 < 96 ≤ 120 = 2 7 − 1 − 7 , tehát Hammiong-kódnál 7 paritásbitre van szükség. Mivel 96 < 120 , ezért az üzenetblokkot ki kel egészíteni 120 − 96 = 24 bittel, és az így kapott 120 bites blokkot lehet kódolni, így a Hamming-kód esetén összesen 24 + 7 = 31 bittel nı a blokk. A kétdimenziós paritásellenırzéshez 12 keresztirányú, 8 hosszirányú paritásbitre, plusz a hosszirányú paritásbitek bájtját kiegészítı keresztirányú paritásbitre, azaz összesen 12 + 8 + 1 = 21 bitre van szükség, tehát a kétdimenziós paritásellenırzés a gazdaságosabb. 36. Mindkét kód 1 hibát képes javítani, így az a gazdaságosabb, amelyhez kevesebb paritásbitre van szükség. 12 × 8 = 96 , és 2 6 − 1 = 63 < 96 + 6 = 102 < 103 = 96 + 7 ≤ 127 = 2 7 − 1 , tehát rövidítéssel a Hamming-kódhoz 7 további bit kell, míg a kétdimenziós ellenırzés esetén 12 × 1 + 9 = 21 , azaz rövidítéssel a Hamming-kód a gazdaságosabb. 37. 139 16 = 0001 0011 1001 2 = 1 0011 1001 2 , és az 1-esek száma páratlan, tehát ebben a bájtban nincs hibajelzés. 07 A 16 = 0000 0111 1010 2 = 0 0111 1010 2 , így itt sem kapunk hibajelzést. Hasonlóan ellenırizve a többi bájtot, pontosan egy karakterben, az 5-ben lesz hibajelzés, itt ugyanis 07 E 16 = 0 0111 1110 2 (a bal szélsı három felesleges 0-t eleve elhagytuk), és ebben a karakterben összesen 6, azaz páros számú 1 áll. Most nézzük a függıleges irányt. A balról számított elsı sávon 1011 0011 12 áll (a beérkezett karakterek bal szélsı bitjeinek sorozata, azaz a feladatban megadott hexadecimális számok elsı jegyeinek jobb szélsı bitjei), és itt az 1-ek száma páros, tehát nincs hibajelzés. A többi sávot hasonlóan ellenırizve (tehát másodikként a hexadecimálisan megadott számok középsı jegyének bal szélsı bitjei stb), egy és csak egy sávon, a balról számított 6-on kapunk hibajelzést, ugyanis itt (tehát a jobb oldali hexadecimális számok bináris alakjának bal szélsı bitjeibıl) 1101 1000 12 a sorozat, és ebben összesen 5, azaz páratlan számú 1 áll. Mivel pontosan egy karakterben és egy sávban van hibajelzés, ezért a hiba javítható. A javításnál az 5. karakter jobbról negyedik bitjét, azaz a jobb szélsı hexadecimális jegy bal szélsı bitjét kell az ellentettjére változtatni, ami azt
120
FELADATOK
jelenti, hogy E 16 = 1110 2 -bıl 0110 2 = 616 lesz. A javítás valamint dekódolás után a 3916 , 7A 16 , F016 , 1B16 , 7616 , 0116 , 0316 , E116 blokkot kapjuk. Amennyiben valóban egyetlen hiba lépett fel, akkor ez volt az eredeti üzenet. Nézzük a további kérdéseket (ezeket már nem részletezzük). a) Hibajelzést kapunk a 2. és az 5. karakternél, tehát ez a két karakter biztosan hibás. Ugyanakkor valamennyi függıleges ellenırzés jó eredményt ad, vagyis nem tudjuk, hogy melyik oszlopban van a hiba, így nem tudunk javítani, de jelezni tudjuk, hogy a 2. és 5. karakter biztosan hibás. b) Egyik karakternél sem lesz hibajelzés, de hibajelzést kapunk a balról számított 3. és 6. oszlopnál, így ismét csak jelezni tudjuk a hibát, de nem tudunk javítani, és azt sem tudjuk, hogy melyik karakter(ek) volt(ak) hibás(ak). c) Hibajelzés lesz a 2. és 5. karakternél, valamint a 6. és 9. sávnál, így megint csak jelezni tudjuk, hogy a 2. és 5. karakter biztosan hibás. d) Hibajelzést kapunk az 5. karakternél, továbbá a 3., 4. és 6. oszlopnál. Jelezni tudjuk, hogy az 5. karakter hibás, de javítani nem tudunk. e) A 2., 5. és 7. karakternél kapunk hibajelzést, valamint a 6. oszlopban. Javítani nem tudunk, de jelezhetjük, hogy az elıbb említett karakterek hibásak. f) Hibajelzést kapunk a 2. karakterben, továbbá a 3. oszlopban. Mivel egy karakterben és egy oszlopban van hibajelzés, ezért „javítunk”: a 2. karakter balról számított 3. bitjét változtatjuk meg, azaz dekódolás után 7216 -ból 3216 -ot kapunk. g) A 2. karakterben, valamint a 3., 6. és 9. oszlopban lesz hibajelzés, így jelezni tudjuk, hogy a 2. karakter hibás, de nem tudunk javítani. h) A 2., 5. és 7. karakterben, valamint a 6. oszlopban lesz hibajelzés. A hibás karaktereket tudjuk jelezni, de nem tudunk javítani. i) A 2., 5. és 7. karakterben, valamint a 6., 8. és 9. oszlopban kapunk hibajelzést. Azt biztosan tudjuk, hogy a megadott karakterek hibásak, de javítani nem tudunk. j) Bár négy hiba biztosan van, sehol nincs hibajelzés, így azt gondoljuk, hogy nem történt hiba. 38. N elıjeles abszolút értékes kódja n biten s ⋅ 2 n −1 + N = a n −1 ⋅ 2 n −1 + M , ahol s = a n −1 az elıjelet mutatja. s értéke 1, ha a szám nem negatív, és 0 az ellenkezı esetben, míg N = M a többi bit által meghatározott érték. Amennyiben n néggyel osztható, akkor a hexadecimális alaknál ez a bit a legmagasabb helyiértékő hexadecimális számjegyén úgy jelentkezik, hogy a számjegy értéke pontosan akkor kisebb, mint 816 , ha az elıjelbit 0. Ügyelni kell arra, hogy elıjeles abszolút értékes kódban jelentkezik a negatív 0, vagyis az a kód, amely az elıjel alapján negatív, de a szám abszolút értéke 0. Ennek hexadecimális alakja, ha n néggyel osztható, olyan, hogy a legmagasabb helyiértékő jegy 816 , az összes többi 016 ; ez a kód a csupa 016 kóddal helyettesítendı. N komplemens kódja s ⋅ 2 n + N , ez N = N -kel egyenlı, ha a szám nem negatív, míg 2 n − N kel, ha N < 0 . Innen rögtön leolvashatjuk a konverziót az elıjeles abszolút értékes kódról a komplemens kódra: ha a legmagasabb helyiértékő bit 0, akkor a két kód megegyezik, ellenkezı esetben elhagyjuk a legmagasabb helyiértékő bitet, és vesszük az így kapott szám 2 n -re vonatkozó komplemensét. Amennyiben a bitek száma többszöröse 4-nek, akkor a hexadecimálisan megadott kód konverziója: ha a legmagasabb helyiértékő hexadecimális jegy kisebb 8-nál, akkor a két kód megegyezik, az ellenkezı esetben ebbıl a legnagyobb helyiértékő jegybıl el kell hagyni 8-at, és az így kapott szám 10 K 016 -ra vett komplemensét venni. Ezt úgy kapjuk, hogy jobbról balra az elsı nem nulla jegyig a számjegyeket változatlanul hagyjuk, az elsı nem nulla jegyet kiegészítjük 1016 = 1610 -re, és a többi jegy helyére ezeknek F16 -ra, vagyis 1510 -re való kiegészítıjét írjuk. Ennek megfelelıen 0016 a 0016 , 1A 16 a 1A 16 , 8016 a 0016 a 0016 , 9A 16 a 1A 16 a E 616 . Most nézzük az áttérést az eltolt nullpontú kódra. Legyen az eltolás értéke K. Amennyiben az eredeti szám nem negatív, akkor az új kód K + N = K + N , míg ha negatív, akkor K + N = K − N . Ha K = 2 n −1 , akkor nem negatív szám esetén ez mindössze annyit jelent, hogy a legmagasabb
Számítógépi matematika
121
helyiértéken álló 0 helyére 1-et kell írni, vagy 4-gyel osztható n esetén a legelsı hexadecimális jegyet meg kell növelni 8-cal, míg ha a szám negatív, akkor K − N = 2 n −1 + 2 n −1 − 2 n −1 + N = 2 n − T ,
(
) (
)
n −1
ahol T az eredeti kód, és ez nem más, mint T 2 -re vonatkozó komplemense. A K = 2 − 1 eset az elızıtıl csupán annyiban tér el, hogy a procedúra végén még 1-et le kell vonni a kapott kódból. Mindezek alapján az eredeti sorrendben elıbb a 128-as, majd a 127-es eltolással kapott kódok 8016 , 9A16 , 8016 és 6616 illetve 7 F16 , 9916 , 7 F16 és 6516 (negatív szám esetén ez egyszerően annyit jelent, hogy valamennyi jegynek vesszük a 15-re való kiegészítıjét.) n
39. Nézzük elıször az elıjeles abszolút értékes kódba való konvertálást. Ha az eltolás értéke K, akkor a kódból a szám értékét úgy kapjuk meg, hogy a kódból kivonjuk K értékét. Ha ez nem negatív, akkor ez az érték közvetlenül a szám elıjeles abszolút értékes kódja, ellenkezı esetben az abszolút értékhez hozzá kell adni 2 n −1 -et. Amennyiben K = 2 n −1 , és az eredeti kód T, akkor nem negatív szám kódjában a legmagasabb helyiértéken álló bit 1, negatív szám esetén pedig 0, vagyis ha a n −1 = 1 , akkor az elıjeles abszolút értékes kódot úgy kapjuk, hogy a bal szélsı bit helyére 0-t írunk, vagy ha n osztható 4gyel, akkor a hexadecimális alakban a bal szélsı jegy értékét 8-cal csökkentjük. Ha viszont a n −1 = 0 ,
(
)
akkor az új kód − T − 2 n −1 + 2 n −1 = 2 n − T , és ez éppen T-nek, vagyis az eredeti kódnak 2 n -re vonatkozó komplemense. Vegyük azonban figyelembe a következıt: eltolt nullpontú kódban a legkisebb ábrázolható szám − K , a legnagyobb pedig 2 n − 1 − K . Ha K = 2 n −1 , akkor tehát a két határ − 2 n −1 és 2 n −1 − 1 . Ugyanakkor elıjeles abszolút értékes kódnál a két határ − 2 n −1 + 1 és 2 n −1 − 1 . A felsı értékkel nincs baj, ám a 2 n −1 -es eltolással ábrázolható legkisebb szám, amelynek a kódja 0, nem ábrázolható elıjeles abszolút értékes kódban. Ennek megfelelıen az új kódok az eredeti sorrendben –, E 616 , 0016 és 1A 16 . Most a komplemens kódra való áttérést vizsgáljuk. Ez azonban könnyő: ha K = 2 n −1 , akkor a két kód közötti konverzió egyszerően abban áll, hogy a bal szélsı bitet megváltoztatjuk, vagy hexadecimális alakban a bal szélen álló jegyet 8-cal növeljük, ha eredetileg kisebb volt 8-nál, ellenkezı esetben 8-cal csökkentjük. Az így kapott kódok rendre 8016 , 9A16 , 0016 és 1A 16 . 40. A feladat lényegében véve azonos az elıbbivel: ha a megadott kódhoz 1-et hozzáadunk, akkor az eredeti szám 128-cal eltolt nullpontú kódját kapjuk. Egyet kell még figyelembe venni: a mostani legnagyobb kódérték 2 n − 1 , és ha ehhez 1-et hozzáadunk, akkor már nem kapunk érvényes kódszót, vagyis ez a kódszó nem alakítható át sem elıjeles abszolút értékes, sem komplemens kóddá. Az eredmény, elıbb az elıjeles abszolút értékes, majd a komplemens kódokkal: FF16 , E516 , 0016 , 0116 , 1B16 , – illetve 8116 , 9B16 , 0016 , 0116 , 1B16 , –. 41. Egy szám akkor és csak akkor negatív, ha komplemens kódjában a legmagasabb helyiértéken álló bit 1, tovább nem negatív szám elıjeles abszolút értékes és komplemens kódja megegyezik. Innen rögtön kapjuk, hogy a 0016 -hoz és 1A 16 -hoz tartozó elıjeles abszolút értékes kód ugyanez az érték, vagyis 0016 és 1A 16 az elıbbi sorrendben. Negatív szám esetén a kódszó 2 n − N = 2 n −1 + M , míg az elıjeles abszolút értékes kódja ugyanezen számnak 2 n −1 + N = 2 n − M , vagyis az elıjegybit elhagyásával kapott szám 2 n -re vonatkozó komplemense. Egyetlen esetben azonban lehetetlen a komplemens kódról áttérni az elıjeles abszolút értékes kódra: az elıbbi kódnál a legkisebb kódolható érték − 2 n −1 , míg a másik kódnál − 2 n −1 + 1 , és a − 2 n −1 komplemens kódja 10 K 0 2 , vagy néggyel osztható bitszám esetén hexadecimálisan 80 K 016 , tehát ennek a komplemens kódnak nincs megfelelıje az elıjeles abszolút értékes kódnál. A konkrét számok esetén az átalakított kódszavak 0016 , 1A 16 , – és E 616 . A komplemens kód és a 2 n −1 -gyel eltolt kód között a legmagasabb helyiértékő bitben van eltérés, így könnyő az átalakítás: 8016 , 9A16 , 0016 és 1A 16 . A 2 n −1 − 1 -es eltoláshoz tartozó kód az elıbbibıl 1 levonásával keletkezik, azonban ügyelni kell arra, hogy az 10 K 0 2 komplemens kódhoz nem tarto-
FELADATOK
122
zik érvényes kódszó ennél az eltolásnál, ugyanis az elıbbi kódszó a − 2 n −1 kódja, míg K = 2 n −1 − 1 eltolással a legkisebb kódolható érték − 2 n −1 + 1 . Ezek után a 127-es eltoláshoz tartozó kódszavak 7 F16 , 9916 , – és 1916 . 42. 48 = 110000 2 = 1.1 ⋅ 2 5 , tehát s = 1 , m = 1.12 és k = 5 , továbbá e = 5 + 127 = 132 = 10000100 2 és m ′ = 1000000000 0000000000 000 2 . A kód 1 10000100 1000000000 0000000000 000 2 = C 2400000 16 . A második esetben 24 ⋅ 2 −138 = 1.1 ⋅ 2 4 ⋅ 2 −138 = 1.1 ⋅ 2 −134 . Mivel − 134 < 1 − 127 = −126 , a szám nem ábrázolható normalizált alakban. 1.1 ⋅ 2 −134 = 0.000000011 ⋅ 2 −126 , ez pozitív, így s = 0 , továbbá e = −126 + 126 = 0 = 00000000 2 és m ′ = 0000000110 0000000000 000 2 , vagyis a megadott szám kódja 0 00000000 0000000110 0000000000 000 2 , ami hexadecimális alakban 0000C00016 . 24 ⋅ 2 −153 = 1.1 ⋅ 2 −149 . A nem nulla mantissza abszolút értékének legkisebb ábrázolható értéke 23 biten 2 −23 , és a kitevı lehetı legkisebb ábrázolható értéke − 126 , így a nullától különbözı legkisebb abszolút értékő ábrázolható szám 2 −23 ⋅ 2 −126 = 2 −149 Ekkora a legkisebb ábrázolható különbség is, ezért 1.1 ⋅ 2 −149 helyett 1 ⋅ 2 −149 ábrázolható, 0 00000000 0000000000 0000000000 0012 = 0000000116 lesz tehát a szám kódja. Az elızı számnál mondottakból következik, hogy 24 ⋅ 2 −154 már kívül esik az ábrázolható számok tartományán, ezért ezt az értéket a gépi nulla, vagyis a csupa 0 bitbıl álló kód reprezentálja, ami hexadecimálisan is csupa 0, vagyis a kód 00000000 16 . 24 ⋅ 2125 = 1.1 ⋅ 2129 . Most e = 129 + 127 = 256 , de ezt 8 biten nem lehet ábrázolni. A kitevı nem csökkenthetı, mert akkor a mantisszát kellene növelni, vagyis ezt a nagy értéket a gépen nem tudjuk ábrázolni, a kitevı túlcsordul, így a végtelennel helyettesítjük, vagyis azzal a kóddal, ahol e a csupa 1bıl álló érték, míg m′ minden jegye 0: 0 11111111 0000000000 0000000000 000 2 , és hexadecimálisan 7F800000 16 .
43.
( ) ( ) (
)(
) ( )
(( ) ) ( )
a. A ⊕ B = AB + AB = A + B A + B = A B + ( AB ) = A B + A B = A ⊕ B b. Ez megegyezik az elızıvel, ha felcseréljük A és B szerepét.
(
) ( AB ) ⊕ ( AC ) = (( AB )AC ) + (AB ( AC )) = (( AB )(A + C )) + ((A + B )( AC )) = = (AB C ) + (A BC ) = A((BC ) + (BC )) = A(B ⊕ C )
c. Az elıbbiek alapján A ⊕ B = A ⊕ B = A ⊕ B = A ⊕ B ≠ A ⊕ B d.
e. Ez nem igaz: ha például A = i = B és C = h , ahol i az igaz és h a hamis logikai érték, akkor a bal oldal A ⊕ (BC ) = i ⊕ (ih ) = i ⊕ h = i és a jobb oldal ( A ⊕ B )( A ⊕ C ) = (i ⊕ i )(i ⊕ h ) = hi = h . f. Nem igaz: ha A igaz, akkor a bal oldal igazságértéke i, míg a jobb oldalé h, függetlenül B és C igazságértékétıl. g. Nem igaz: ha A = i = B és C = h , akkor a bal oldal értéke h, ugyanakkor a jobb oldal értéke i.
( ) ( ) (( )( )) ( ) ( A + B ) ⊕ ( A + C ) = (( A + B )A + C ) + A + B( A + C ) = = ((A B ) + A + C )(A + B + (A C )) = A + ((A B ) + C )(B + (A C )) = = A + (A B C ) + (BC ) = A + (A B C ) + (A B C ) + (BC ) = A + (B C ) + (BC )
h. A + B ⊕ C = A + BC + BC = A + B + C B + C = A + B C + (BC )
44. vb s = v B log 2 8 = 3v B = 9600 bit s
Számítógépi matematika
123
45. 65536 = 216 , vagyis minden ponthoz 16 bitre, azaz két bájtra van szükség, így a memória mérete 2 ⋅ 768 KB = 1536 KB . Mivel 1 MB = 1024 KB , ezért két darab memóriaelemre van szükség, tehát öszszesen 2 MB lesz a videomemória kapacitása. 46. dpi a dot per inch rövidítése. Az inch magyarul hüvelyk (németül Zoll, kb. 2.54 cm ), és a dpi a 210 297 hüvelyenkénti pontok száma. Most egy lap × 600 × × 600 = 4961 × 7016 = 34806376 25,4 25,4 pont, és mivel fekete-fehér reprezentációról van szó, ezért pontonként 1 bitnyi memóriára van szükség. Ez tehát azt jelenti, hogy a szükséges memóriaméret 34806376 bit = 4350797 bájt = 4.15 MB (vigyázat, 1 MB nem 10 6 bájt!). 47. Mivel a PC tartalma 5, ezért a soron következı utasítás az 5. címen található, és ez C016 = 1100 0000 2 . A mőveleti kód 110 2 = 6 , ez a komplementáló utasítás, tehát a további bitek nem érdekesek. Az AC tartalma 1516 , ennek komplemense EB16 , ez lesz tehát az AC új tartalma. Az utasítás kiolvasása után a PC tartalma 1-gyel megnıtt, tehát a soron következı utasítást a 6. címrıl vesszük, és közben ismét megnı PC tartalma, vagyis már 7 áll benne. A kiolvasott utasítás 5116 = 0101 00012 . 010 2 = 2 , ez összeadó utasítás, és az operandusok egyike az akkumulátorban lévı érték, EB16 , a másik a memória 10001 2 = 17 -es címén lévı adat, vagyis 1016 . Az összeg EB16 + 1016 = FB16 . A következı, 3. utasítás a 7-es címen található, és a kiolvasása után a PC tartalma 8 lesz. A kiolvasott utasítás A516 = 1010 01012 . Az operációs kód 1012 = 5 , és ez a JN M utasítás, vagyis ugrás, ha az akkumulátor tartalma negatív, amit az SR regiszter SF bitje jelez: 0, ha az utoljára végrehajtott aritmetikai utasítás eredménye nem negatív, és 1, ha ez az eredmény negatív. A legutolsó aritmetikai utasítás az elızı összeadás volt, az eredmény FB16 , és ez egy negatív szám komplemens kódja, így SF értéke 1. Ekkor a gépnek ugrania kell, vagyis a program az ugró utasítás címrészében található címen, a 00101 2 = 5 -ös címen folytatódik, tehát ezt kell a gépnek beírnia a PC-be, így tehát az utasítás befejezése után a PC tartalma 0516 . Az AC tartalmát már ismerjük, hiszen ez ennek az utasításnak a végrehajtása közben nem változott, azaz az AC-ben FB16 áll. Végül az állapotregiszter bitjei: SF-et már tudjuk, ez 1, az összeadásnál nem keletkezett sem átvitel, sem túlcsordulás, így CF=0 és OF=0, és az eredmény nem nulla, tehát ZF=0. 48. Egy sáv kapacitása 1.44 ⋅ (1024 )2 2 80 = 9438 B (a 2 azért szerepel, mert a lemez mindkét oldalát használjuk). Mivel a fordulatszám másodpercenként 6, ezért 1 másodperc alatt 6 sávnyi adatot tudunk átvinni, azaz 55.3 kB -ot, így az átviteli sebesség 55.3 kB s (persze csak akkor, ha legfeljebb a lemez két oldalán azonos helyen található két sávról olvasunk le adatot, vagy ilyenre írunk, hiszen ellenkezı esetben a fejnek el kell mennie egyik sávról egy másikra, ami különösen hajlékony lemez esetén tetemes idıt vesz igénybe). 49. 800 bpi azt jelenti, hogy 1 inch hosszúságon, azaz 2.54 cm -en sávonként 800 bit helyezkedhet el. Mivel a szalag 1 s alatt 6 m-t tesz meg, ezért 1 s alatt 600 2.54 × 800 = 188976 .3779 bájt kerül átvitelre, vagyis az átviteli sebesség 188976 .3779 1024 = 184.5472 ≈ 185 kB s . 50. Egy sor tartalmaz 16 × 8 = 128 adatbitet, 1 bit jelzi azt, hogy az adott sorban érvényes adat van, 1 bit mutatja a változást, ez eddig 130 bit. 1 MB címzéséhez 20 bit kell, ekkor egy 16-tal osztható cím megadásához 20 − 4 = 16 bitre van szükség, vagyis a cache-tárban a címrész felsı 16 bitjét is tárolni kell, így egy sor tárolásához összesen 130 + 16 = 146 bitre van szükség.
FELADATOK
124
51. 16 × 8 = 128 adatbit, 1 érvényességi bit és egy módosításjelzı bit van egy-egy sorban, ez összesen 130 bit, a fennmaradó 20 bit mutatja a 16 bájt operatív memóriabeli címét. Mivel a 16 bájt címzéséhez 4 bit kell, ezért a teljes memória címzése 24 bittel lehetséges, amely 16 MB -ot tesz lehetıvé. 52. a. Ahol 0 van, ott nem változik az íróáram, míg 1-nél megfordul, így
+I
1
1
0
1
0
0
0
1
−I
b. Minden bit elıtt, valamint 1-nél a bit közepén is megfordul az íróáram:
+I
1
1
0
1
0
0
0
1
−I
c. Minden 1-es közepén megfordul az íróáram, valamint a 0 elején akkor, ha elıtte bitközépen nem volt változás:
+I
1
1
0
1
0
0
0
1
−I
53. a. Mivel FM felírásnál minden bitnél legalább egy, míg MFM felírásnál legalább minden második bitnél van íróáram-változás, és így kiolvasáskor jel, ezért az ábra csak NRZI rögzítési módra vonatkozhat. Ekkor ahol van kiolvasott jel, ott eredetileg 1, míg ahol nincs jel, ott 0 állt. Ennek megfelelıen a felírt adat 11010001 2 . b. NRZI és MFM esetén 1 bithez legfeljebb 1 íróáram-változás, és így legfeljebb 1 kiolvasott jel tartozik, így ez az ábra nem felelhet meg NRZI és MFM felírásnak. FM-nél minden bit elején van változás, ez csupán szinkronizációs információ, és akkor és csak akkor van 1, ha a bit közepén is van változás, tehát kiolvasott jel. Ezek alapján az eredeti bitsorozat 11010001 2 . c. NRZI-nél egy-egy bithez tartozó idıintervallumnak mindig azonos helyén van íróáramváltozás (már ha egyáltalán változik az áram), így ez a jel nem lehet NRZI felíráshoz tartozó olvasott jelsorozat. FM-nél minden bit elején van változás, és így kiolvasott jel, amibıl következik, hogy ez nem lehet FM-jelsorozat sem, vagyis a felírási mód MFM. Most akkor és csak akkor van 1, ha a bit közepén történik áramváltás, így a kiolvasott jelsorozat az 11010001 2 bitsorozathoz tartozik. 54. a. Mivel FM felírásnál minden bitnél legalább egy, míg MFM felírásnál legalább minden második bitnél van íróáram-változás, ezért az ábra csak NRZI rögzítési módra vonatkozhat. Ekkor ahol van változás, ott eredetileg 1, míg ahol nincs, ott 0 állt. Ennek megfelelıen a felírt adat 11010001 2 .
Számítógépi matematika
125
b. NRZI és MFM esetén 1 bithez legfeljebb 1 íróáram-változás tartozik, így ez az ábra nem felelhet meg NRZI és MFM felírásnak. FM-nél minden bit elején van változás, ez csupán szinkronizációs információ, és akkor és csak akkor van 1, ha a bit közepén is van változás. Ezek alapján az eredeti bitsorozat 11010001 2 . c. NRZI-nél egy-egy bithez tartozó idıintervallumnak mindig azonos helyén van íróáramváltozás (már ha egyáltalán változik az áram), így ez a jel nem lehet NRZI felíráshoz tartozó jelsorozat. FM-nél minden bit elején van változás, amibıl következik, hogy ez nem lehet FMjelsorozat sem, vagyis a felírási mód MFM. Most akkor és csak akkor van 1, ha a bit közepén történik áramváltás, így a jelsorozat az 11010001 2 bitsorozathoz tartozik. 55. 8230 A 0B616 -ban 8216 az utasítás kódja, 316 az elsı operandust tartalmazó regiszter sorszáma, 016 utal az index- és A 16 a bázisregiszterre, végül az eltolás értéke 0B616 . A 3-as regiszter tartalma DC 4E 23A 216 , ez tehát az elsı operandus (feltéve, hogy az utasításkód kétoperandusos mővelet kódja). A 0. regiszter index- vagy bázisregiszter pozícióban azt jelenti, hogy nem használunk az adott utasítás címszámításánál index- vagy bázisregisztert, tehát most ebben az utasításban indexregiszterre nem hivatkozunk. A bázisregiszter sorszáma A 16 = 10 , ennek tartalma 030 A 02 BA 16 , és ehhez kell hozzáadni az eltolás értékét, 0B616 -ot. Ebbıl azt kapjuk, hogy a második operandus memóriabeli címe 030 A 02BA 16 + 0B616 = 030 A 0370 16 . 56. 5675 8 = 101 110 111 1012 , és ebben az utasításban mind az indirekcióra, mind az indexelésre vonatkozó bit 1. A címrész értéke 75 8 ; most két eset lehetséges (ez géptıl függ): vagy a 75 8 -at indexeljük, és az így kapott címen található adat a tényleges adatcím, vagy fordítva, a 75 8 címen lévı adatot indexelve kapjuk meg az operandus memóriabeli címét. Az elsı esetben 75 8 + 0010 8 = 0105 8 , és ezen a címen 4440 8 áll, vagyis ez lesz az operandus címe, míg a másik esetben a 75 8 cím tartalma 7240 8 , és ha ezt indexeljük, akkor a keresett címet kapjuk, azaz most az adat tényleges címe 7240 8 + 0010 8 = 7250 8 . 57. CA 45A 20616 utolsó 20 bitje 5A 206 16 . 516 lesz az indexregiszter, A 16 a bázisregiszter, és 20616 az eltolás, így a logikai cím az 5-ös és 10-es regiszter tartalmának és 20616 -nak az összege, vagyis a konkrét értékekkel FB4A346 A 16 FB4A346A 16 + 04B622BA 16 + 20616 = 1 0000592A 16 . A legelsı 1 levágódik, így a kiszámolt logikai cím 0000592 A 16 , amelybıl 516 a lapszám, és 92A 16 a lapon belüli sorszám. A fent megadott 8 hexadecimális jegybıl álló adatok két-két lapra vonatkoznak, hiszen egy laphoz csak 16 bit tartozik, így az 5. lapra vonatkozó információk a 3. adat második 16 bitjében találhatóak, ami 132B16 . A két utolsó bit értéke 11, ebbıl az elıbbi mutatja, hogy ez a lapbejegyzés az operatív memóriára vonatkozik. Az elsı 14 bit adja a lap fizikai sorszámát, ehhez kell hozzáláncolni a logikai cím alsó 12 bitjét, vagyis 0001001100 1010100100 101010 2 = 004CA 92A 16 a tényleges fizikai cím. 58. CA 45A 20616 utolsó 20 bitje 5A 206 16 . 516 lesz az indexregiszter, A 16 a bázisregiszter, és 20616 az eltolás, így a logikai cím az 5-ös és 10-es regiszter tartalmának és 20616 -nak az összege, vagyis a konkrét értékekkel FB4A346 A 16 FB4A346A 16 + 04B622BA 16 + 20616 = 1 0000592A 16 . A legelsı 1 levágódik, így a kiszámolt logikai cím 0000592 A 16 , amelybıl 516 a szegmensszám, és 92A 16 a szegmensen belüli sorszám. A szegmenstáblában az 5. szegmensre vonatkozó bejegyzés 024A346 A 16 , amelybıl a legfelsı 4 bit, vagyis az elsı 0 érdektelen. Az utolsó 2 bit értéke 10, az elsı szerint a bejegyzés érvényes, és a szegmens a memória 0010010010 1000110100 011010 2 = 00928 D1A 16 címén kezdıdik. Az eltolás értéke 92A 16 , így a keresett adat a memória 00928 D1A 16 + 92 A 16 = 00929644 16 -os címén található.
126
FELADATOK
59. CA 45A 20616 utolsó 20 bitje 5A 206 16 . 516 lesz az indexregiszter, A 16 a bázisregiszter, és 20616 az eltolás, így a logikai cím az 5-ös és 10-es regiszter tartalmának és 20616 -nak az összege, vagyis a konkrét értékekkel FB4A346 A 16 FB4A346A 16 + 04B622BA 16 + 20616 = 1 0000592A 16 . A legelsı 1 levágódik, így a kiszámolt logikai cím 0000592 A 16 , amelybıl 516 a lapszám, és 92A 16 a lapon belüli sorszám. A fent megadott 8 hexadecimális jegybıl álló adatok két-két lapra vonatkoznak, hiszen egy laphoz csak 16 bit tartozik, így az 5. lapra vonatkozó információk a 3. adat második 16 bitjében találhatóak, ami 132C16 . A két utolsó bit értéke 00, ebbıl az elıbbi mutatja, hogy ez a lapbejegyzés a háttértárolóbeli címet adja, vagyis az adat nincs az operatív memóriában, azt elıbb be kell olvasni a háttértárolóról. 60. CA 45A 20616 utolsó 20 bitje 5A 206 16 . 516 lesz az indexregiszter, A 16 a bázisregiszter, és 20616 az eltolás, így a logikai cím az 5-ös és 10-es regiszter tartalmának és 20616 -nak az összege, vagyis a konkrét értékekkel FB4A346A 16 + 04B622BA 16 + 20616 = 1 0000592A 16 . A legelsı 1 levágódik, így a kiszámolt logikai cím 0000592 A 16 , amelybıl 516 a szegmensszám, és 92A 16 a szegmensen belüli sorszám. A szegmenstáblában az 5. szegmensre vonatkozó bejegyzés 041300 A016 , amelybıl a legfelsı 4 bit, vagyis az elsı 0 érdektelen. Az utolsó 2 bit értéke 00, ebbıl az elıbbi mutatja, hogy ez a szegmensbejegyzés a háttértárolóbeli címet adja, vagyis az adat nincs az operatív memóriában, azt elıbb be kell olvasni a háttértárolóról.
TÁRGYMUTATÓ A,Á ábécé cirill ~ · 20 görög ~ · 20 kopt ~ · 20 latin ~ · 20 adat numerikus ~ · 21 alapmővelet · 8 algoritmus · 7 alulcsordulás lebegıpontos ~ · 59 átalakítás analóg-digitál ~ · 17 digitál-analóg ~ · 17 áthozat · 50, 53 átvitel · 50, 52 ~bit · 50, 52 átviteljelzı · 50
B bájt · 19 BCD-szám · 32 bető arab ~ · 20 bit · 19 elıjegy~ · 37, 44 elıjel~ · 36, 40 státusz~ · 52 Boole-függvény · 77 ~-ek száma · 77 affin · 79 deMorgan azonosság · 79 diszjunkció · 78 egyváltozós ~-ek · 77 ekvivalencia · 79 implikáció · 79 inhibíció · 80 kétaváltozós ~-ek · 78 kizáró vagy · 79 konjunkció · 78 lineáris ~ · 79 logikai szorzás · 78 logikai vagy · 78 NAND · 79 nem-és · 79 nem-vagy · 79 NOR · 79 nullaváltozós ~-ek · 77 Pierce-vonás · 79 Sheffer-vonás · 79 Boole-függvénylogikai és · 78 byte · Lásd bájt
C carry · Lásd átvitel, Lásd átvitel
~ bit · Lásd átvitel:~bit ~bit · 52 CRC · 88
D dekódolás · 19 digit · 7 digitus · 7 duplaszó · 19
E,É ellentett ~képzés · 54 ellentett-képzés · 77 elıjel ~-kiterjesztés · 68 ~váltás · 53 BCD-számok ~váltása · 59 elıjeles abszolút értékes számok ~váltása · 54 eltolt nullpontú számok ~váltása · 53 komplemens kódolású számok ~váltása · 54 szorzat ~e · 62 elıjel-kiterjesztés bináris számok ~e · 68
F félbájt legértékesebb ~ · 21 legkevésbé értékes ~ · 21 felírás bináris ~ · 22 kettes számrendszerbeli ~ · 22 félszó · 19 flag · 52 átvitel~ · 52 carry ~ · 50 carry~ · 52 elıjel~ · 52, 57 overflow ~ · 50 túlcsordulás~ · 54 zéró~ · 52, 57 fledolgozó egység · 9 függvény sávhatárolt ~ · 11
G gépi nulla · 45
H hiba abszolút ~ · 34 relatív ~ · 34
128 Horner módszer · 26 Horner-módszer · 29 hosszkiterjesztés · 67 elıjeles abszolút értékes számok ~e · 67 komplemens kódú számok ~e · 68
I,Í írásjel japán ~ · 20 kínai ~ · 20 kóreai ~ · 20
J jel
TÁRGYMUTATÓ ~ kód · 40 szám ~e · 40 konvertálás · 32 konverzió ~ komplemens és eltolt nullpontú kód között · 44 A/D ~ · 17 bináris-hexadecimális ~ · 31 D/A ~ · 17 hexadecimális-bináris ~ · 31 szám~ · 22 tört ~ja · 28 kvantálás · 13 egyenletes ~ · 13 kvantált függvény · 13 kvantum · 13 kvonás eltolt nullpontú bináris számok ~a · 50
analóg ~ · 7, 17 digitális · 7 digitális ~ · 17 mintavett ~ · 11 mintavett kvantált ~ · 16 jelkészlet bopomofo ~ · 20 CJK · 20
L
K
memória · 8 memóriacella · 86 mintavételezés · 10 egyenletes ~ · 10 mintavételi frekvencia · 11 mintavételezett függvény · 10 mintavételi idıpont · 10 MSN · Lásd Most Significanr Nibble mővelet additív · 49 additív ~ · 51 egyváltozós ~ · 54 kétváltozós ~ · 51 multiplikatív · 50 multiplikatív ~ · 60 összeadás · 51 összeg · 52 unér ~ · 54
kétdimenziós paritásellenırzés · 88 kivonás BCD-számok ~a · 58, 60 elıjel nélküli bináris számok ~a · 50 elıjeles abszolút értékes bináris számok ~a · 51 eıjel nélküli számok l~a · 53 fixpontos egész számok ~a · 53 lebegıpontos számok ~a · 58 kód · 19 alfabetikus ~ · 20 alfanumerikus ~ · 20 ASCII ~ · 19 BCD-~ · 33 bináris komplemens ~ · 44 binárisan kódolt decimális · 33 Binary Coded Decimal · 33 EBCDIC ~ · 19 elıjeles abszolút értékes ~ · 36 eltolt nullpontú ~ · 36 Hamming-~ · 88 kiterjesztett ASCII-~ · 22 komplemens ~ · 36, 40 negatív szám ~ja · 40 nem negatív szám ~ja · 40 nem szám ~ja · 45 numerikus ~ · 21 numerikus rész · 33 rendezéstartó ~ · 39 Unicode · 20 végtelen ~ja · 45 zóna rész · 33 kódolás · 19 elıjeles abszolút értékes ~ · 40 eltolt nullpontú ~ · 38 numerikus ~ · 21 komplemens · 37
lineáris B · 20 LRC · 88 LSN · Lásd Least Significanr Nibble
M
N negálás · 77 negatív nulla · 36, 40 Neumann-elv · 8 Nibble Least Significant ~ · 21 Most Significant ~ · 21
O,Ó operandus · 51 osztás fixpontos számok ~a · 74 lebegıpontos számok ~a · 75 maradékos ~ · 62
Számítógépi matematika overflow · Lásd túlcsordulás
Ö,İ összeadás BCD-számok ~a · 58, 59 elıjel nélküli bináris számok ~a · 50 elıjel nélküli számok ~a · 51 elıjeles abszolút értékes bináris számok ~a · 50 elıjeles abszolút értékes számok ~a · 55 eltolt nullpontú bináris számok ~a · 50 eltolt nullpontú számok ~a · 55 félösszeadó · 82 fixpontos egész számok ~a · 53 komplemens bináris számok ~a · 51 komplemns kódú számok ~a · 56 lebegıpontos számok ~a · 57, 58 teljes összeadó · 82
P paritásbit · 19, 87 program · 8 programtárolás · 8
R r-edespont · 34 regiszter állapot~ · 50, 52 státusz~ · 50, 52
S sávhatár · 11 Shannon, Claude Elwood · 11
Sz számábrázolás bázis · 45, 46 csonkolás · 35 elıjel nélküli ~ · 34 elıjeles ~ · 36 elıjeles abszolút értékes ~ · 36 elıjeles BCD-~ · 44 eltolt nullpontú ~ · 36 fixpontos ~ · 34 fixpontos egész ~ · 35 fixpontos tört ~ · 35 karakterisztika · 46 kitevı · 46 lebegıpontos ~ · 45, 46 mantissza · 45, 46 nem normalizált lebegıpontos ~ · 45, 46 nem rendezéstrató ~ · 36 normalizált lebegıpontos ~ · 45, 46 rendezéstartó ~ · 36 számítógép analóg ~ · 7
cél~ · 8 digitális ~ · 7 Neumann-elvő ~ · 8 szószervezéső ~ · 19 tárolt programú ~ · 8 univerzális ~ · 8 számjegy · 7 decimális ~ek · 19 r-alapú számrendszer ~ei · 19 számrendszer hexadecimális ~ · 19 kettes ~ · 8 nyolcas ~ · 19 oktális ~ · 19 tizenhatos ~ · 19 számtartomány ábrázolható · 34 szó · 19 szorzás BCD-számok ~a · 74 egész számok abszolút értékének ~a · 68 elıjeles abszolút értékes számok ~a · 61 komplemens kódú számok ~a · 61, 66 lebegıpontos számok ~a · 74 lebegıpontoss számok ~a · 62 szótagírás hiragana · 20 japán ~ · 20 katakana · 20
T tetrád · 31 tört bináris ~ · 27, 29 decimális ~ · 29 kettedes ~ · 28 tizedes ~ · 28 véges decimális ~ · 26 véges hosszúságú ~ · 28 véges kettedes ~ · 28 véges tizedes ~ · 28 végtelen hosszúságú ~ · 28 triád · 32 túlcsordulás · 50, 54 ~bit · 50 komplemens kódú számok ~a összeadásnál · 56 lebegıpontos ~ · 59
U,Ú utasítás · 8
V változó fiktív ~ · 78 lényeges ~ · 78 végrehajtás szekvenciális ~ · 8 VRC · 88
129
IRODALOMJEGYZÉK
1. Salánki József 2. Rupprich Péter 3. Cserny László
A számítástechnika alapjai Tankönyvkiadó, 1981 Digitális aritmetika Tankönyvkiadó, 1976 Mikroszámítógépek LSI Oktatóközpont, 1996