Számrendszerek közötti átváltások 10-es számrendszerből tetszőleges számrendszerbe Legyen az átváltani kívánt szám: 723, 10-es számrendszerben. Ha 10-esből bármilyen számrendszerbe kívánunk átváltani, az alábbi algoritmust kell követnünk:
Osszuk az eredeti számot a cél számrendszer alapszámával (2-es számrendszerben ez 2, stb.).
A maradékot jegyezzük fel jobb oldalra.
Az osztás eredményét írjuk le a szám alá. Ha az nem 0, osszuk újra az alapszámmal.
Folytassuk mindezt addig, míg nem jutunk el 0-ig.
2-esbe:
8-asba:
Ezek után a számot „alulról-felfelé” olvassuk. Így az eredmények: 2-esben: 1011010011 8-asban: 1323 16-osban: 2D3
16-osba:
Tetszőleges számrendszerből 10-es számrendszerbe: Bármely számrendszerben is vagyunk, ha 10-es számrendszerbe szeretnénk vissza váltani, a szám egyes számjegyeit megszorozzuk a számrendszer alapszámának megfelelő hatványával. Szemléltetésképp kezdjük azzal, hogy egy 10-es számrendszerbeli számot váltunk át 10-es számrendszerbe…
Tehát a szám jobbról első számjegye fogja jelenteni a 0. hatványt. Mellette balról az 1., stb… Most váltsuk vissza az előzőleg kapott 2-es, 8-as, 16-os számrendszerbeli számokat 10-essé:
2-esből:
8-asból:
16-osból:
Nem 10-esből egy másik nem 10-esbe Ha ilyen feladatot kapunk (pl. 2-esből 8-asba), akkor követhetjük azt a módszert, hogy először átváltunk 10-es számrendszerbe, majd átváltunk a kívánt számrendszerbe. Ez azonban időigényes. 2-es, 8-as, 16-os számrendszerek között (mivel 2 hatványai), gyorsabban is át lehet váltani.
2-esből 8-asba: Mivel 2^3 = 8, ezért az eredeti kettes számrendszerbeli szám számjegyeit 3-asával (jobbról balra) csoportokba fogjuk. Ezután kiszámoljuk, az egyes csoportok értékét, ezek fogják adni a 8-as számrendszerbeli szám számjegyeit.
2-esből 16-osba: Előző módszerhez hasonló, de mivel 2^4 = 16, ezért itt 4-esével fogjuk csoportba a számjegyeket.
8-asból 2-esbe: A 2-esből 8-asba módszer fordítottja. Fogjuk a 8-as számrendszerbeli szám számjegyeit, majd azokat egyenként visszaváltjuk 3 jegyből álló, kettes számrendszerbeli megfelelőjükre. (Ehhez kell, hogy kettő hatványait gyorsan tudjuk fejben számolni, azonban itt még elég kis számokról van szó, így nem túl nehéz a feladat).
(Kettes számrendszerben a szám elején lévő 0-kat elhagyhatjuk, így az eredeti számot kapjuk) 16-osból 2-esbe: Hasonló az előzőhöz, de nem 3 jegyet, hanem 4-et kell alkotnunk a 16-os számrendszerbeli szám egyes jegyeiből…
Igazságtáblák NOT (tagadás) Eredeti érték ellentettje. bemenet
kimenet
A
NOT A
0
1
1
0
AND (és) Igaz, ha mindkét érték igaz. Különben hamis. bemenet
kimenet
A
B
A AND B
0
0
0
0
1
0
1
0
0
1
1
1
OR (vagy) Igaz, ha legalább az egyik érték igaz. Különben hamis. bemenet
kimenet
A
B
A OR B
0
0
0
0
1
1
1
0
1
1
1
1
XOR (kizáró vagy) Igaz, ha pontosan egy feltétel igaz. Ha kettő igaz, vagy egy sem, akkor hamisat ad vissza. bemenet
kimenet
A
B
A XOR B
0
0
0
0
1
1
1
0
1
1
1
0
NAND (NOT AND) Az AND művelet ellenkezője (tagadása). bemenet
kimenet
A
B
A NAND B
0
0
1
0
1
1
1
0
1
1
1
0
NOR (NOT OR) Az OR művelet tagadása. bemenet
kimenet
A
B
A NOR B
0
0
1
0
1
0
1
0
0
1
1
0
XNOR (X NOT OR) A kizáró vagy tagadása. bemenet
kimenet
A
B
A XNOR B
0
0
1
0
1
0
1
0
0
1
1
1
Bitenkénti műveletek Negálás Jelölése: ~ Az eredeti szám minden bitjét az ellenkezőjére módosítjuk. Ha nem 2-es számrendszerbeli számot kapunk, először váltsuk át kettesre, majd negálhatjuk. Például: ~ 1011010011 = 0100101100
Bitenkénti AND Jelölése: & Két számot bitenként „és-elünk”, azaz végrehajtjuk rajtuk bitenként az AND igazságtáblában látott műveleteket. (Ha nem 2-es számrendszerben vannak, alakítsuk át őket először). Egyik szám: 110100 Másik: 11011010 110100 &11011010 00010000
Bitenkénti OR Jelölése: | Két számot bitenként „vagy-olunk”, azaz végrehajtjuk rajtuk bitenként az OR igazságtáblában látott műveleteket. (Ha nem 2-es számrendszerben vannak, alakítsuk át őket először). Egyik szám: 110100 Másik: 11011010 110100 | 11011010 11111110
Negatív számok ábrázolása – kettes komplemens képzés Ha egy változónak nem adjuk meg, hogy az unsigned legyen, ha negatív értéket adunk, a számítógépes számábrázolásban valahogyan jelölni kell ezt. Erre vezették be először az előjelbitet. 0 jelenti a pozitív, 1 a negatív számot. Így azonban a 0 értéket kétféleképpen is ábrázolhatjuk (pozitív 0, negatív 0). Ezért a negatív számok ábrázolására a kettes komplemenst használják. Ez elég egyszerű: Az eredeti szám minden bitjét negáljuk (egyes komplemens) Adjunk hozzá 1-et az eredményhez (kettes komplemens) Ábrázoljuk kettes komplemens módszerrel a (-723) értéket! A korábbiakban már kiszámoltuk, hogy 723 bináris értéke: 1011010011 Ha ezt 32 biten tároljuk, így néz ki: 00000000000000000000001011010011 Ezt negáljuk (egyes komplemenst képzünk): 11111111111111111111110100101100 Ehhez adjunk hozzá egyet (kettes komplemenst képzünk): 11111111111111111111110100101101 A negatív szám tehát így fog kinézni gépi ábrázolásban. (Ha ebből vissza szeretnénk nyerni a szám abszolút értékét (723), akkor először kivonunk belőle 1-et, majd negáljuk minden bitjét, és megkapjuk az eredeti számot. Lényegében az eredeti műveletet végezzük el, csak fordítva…)
Bitléptetés – előjeltelen számok A biteket léptethetjük jobbra vagy balra. A jobbra léptetés 2-vel való osztásnak, a balra léptetés 2-vel való szorzásnak felel meg. (Gondoljuk kicsit végig a hátterét, miért is van ez…)
Balra léptetés:
Jobbra léptetés: szám >> x
szám << x
Assembly-ben: SHL (Shift Left) Assembly-ben: SHR (Shift Right)
(Az adott számot x lépéssel balra, vagy jobbra toljuk) Ha előjeltelen szám bitjeit szeretnénk léptetgetni, az viszonylag triviális.
Feladat:
723 << 2
(léptessük el a 723 decimális szám bitjeit 2-vel balra)
723 decimális szám bináris értékét már kiszámoltuk. Ez 32 biten ábrázolva: 00000000000000000000001011010011 Ezt 2-vel balra léptetve az eredmény: 00000000000000000000101101001100
(Az egészet eltoltuk kettővel balra. Az eredetileg a szám bal oldalán lévő két darab 0 „elveszett”, jobbról pedig bejött két darab 0). Így
723 << 2
=
2892
(Az eredmény ugyanaz, mint 723 * 2 * 2)
Feladat:
723 >> 3
(léptessük el a 723 decimális szám bitjeit 3-al jobbra)
723 decimális szám bináris értékét már kiszámoltuk. Ez 32 biten ábrázolva: 00000000000000000000001011010011 Ezt 3-al jobbra léptetve az eredmény: 00000000000000000000000001011010 (Jobb oldalról „elveszik” 3 darab bit. Bal oldalról viszont bejön 3 darab 0) Így
723 >> 3
=
90
(Az eredmény ugyanaz, mint 723 / 2 / 2 / 2, természetesen tizedes jegyek nélkül számolva)
Bitléptetés – előjeles számok A bitléptetés lényege hasonló az előjeltelen számokkal való léptetéshez. Azonban, ha pusztán az előző módszereket használnánk, az eredeti előjel jobbra léptetésnél elveszne. Ennek kiküszöbölésére az előjeles számok bitléptetéséhez külön gépi utasítások léteznek. C / C++ szintjén ezt nem érzékeljük, azonban más Assembly utasításnak felelnek meg az alábbiak, mint az előzőleg látottak:
Balra léptetés:
Jobbra léptetés: negatív szám >> x
negatív szám << x
Assembly-ben: SAL (Shift Arithmetic Left) Assembly-ben: SAR (Shift Arithmetic Right)
(Az adott negatív számot x lépéssel balra, vagy jobbra toljuk) A balra léptetés előjeles szám esetén pontosan ugyanúgy működik, mint előjeltelennél!
Feladat:
-723 << 2
(léptessük el a -723 decimális szám bitjeit 2-vel balra)
723 decimális szám bináris értékét már kiszámoltuk. Ez 32 biten ábrázolva: 00000000000000000000001011010011 Ennek kell vennünk a kettes komplemensét, hiszen negatív szám. A korábbiakban már ezt is kiszámoltuk: 11111111111111111111110100101101 Ezt 2-vel balra léptetve az eredmény: 11111111111111111111010010110100 A balra léptetés előjeles szám esetén pontosan ugyanúgy működik, mint előjeltelennél! Így
-723 << 2
=
-2892
(Az eredmény ugyanaz, mint (-723) * 2 * 2)
Feladat:
-723 >> 3
(léptessük el a -723 decimális szám bitjeit 3-al jobbra)
A negatív szám binárisan így nézett ki: 11111111111111111111110100101101 Ha ezt szimplán eltolnánk jobbra, 0 jönne be balról, így az előjel információk elvesznének. Ezért, ha előjeles számról van szó, gépi szinten a SAR utasítás hívódik, mely balról 1-est fog behozni. Így a 3-al jobbra tolás eredménye: 11111111111111111111111110100101 Jobbról „elveszítettünk” 3 bitet, balról pedig csupa egyes jött be. Így
-723 >> 3
=
-91
(Látható, hogy előjeltelen 723 esetén a jobbra 3-al eltolás eredménye 90 volt. Itt azonban -91, tehát abszolút értékben 1 az eltérés. Ezt a kettes komplemens számábrázolás okozza. Az eredmény ugyanaz, mint 723 / 2 / 2 / 2, azonban az előjeltelen példához képest itt nem lefelé „kerekítődött” a szám értéke, hanem felfelé, így 91 lett.)
Logikai műveletek Példák… Logikai műveleteknél csupán az igazságtáblákat kell ismernünk. Egy példán keresztül megnézünk néhány if szerkezetet, melyekkel kiderül, a teljes feltétel igaz, vagy hamis értéket ad vissza. C-ben nincs bool típus (C++-ban már van), ezért most legyen: #define true 1 #define false 0
(true-nak 1 az értéke, false-nak 0…) Az ilyen feladatokat próbáljuk meg a belső zárójelektől indulva, mindig egyszerre csak két feltételt nézve végrehajtani az igazságtáblák segítségével. Példa1:
Ez tehát hamis lesz.
Példa2:
Ez igaz lesz. Példa3:
Ez is igaz lesz.