2. Számábrázolás¶
Hol kerülnek tárolásra az adatok?
Memória
Háttértár
A számábrázolás témakörében nem szükséges foglalkoznunk a bitek tárolásának fizikális megvalósításával.
Memória
Lineárisan címezhető rekeszek.
A címzéshez nem negatív egészeket használunk.
A pointer/mutató tulajdonképpen egy memóriacímet jelent.
A bit szintű elérés általában nem biztosított. Byte-ok szintjén kell dolgozni, hogy hozzáférjünk a bitekhez.
A tárolókra szokás buffer (angol nyelvből) vagy puffer (német nyelvből) néven hivatkozni.
Adatok vizsgálata
Memória esetében memory dump
Az adatok megtekintéséhez, szerkesztéséhez hexadecimális szerkesztők használhatók.
Hex Editor, Hexa Editor, Binary Editor
Véges ábrázolás¶
Alapvetően bitmintákat rendelünk szimbólumokhoz.
Véges számú byte-on véges számú bitminta van.
Mit jelenthet a következő byte?
10110010
Az ábrázolt bitsorozatnak van két kitüntetett bitje:
MSB: Most Significant Bit (legnagyobb helyiértéken szereplő bit)
LSB: Least Significant Bit (legkisebb helyiértéken szereplő bit)
Ábrázolással kapcsolatosan egy további leírás:
Előjel nélküli egészek¶
A 2-es számrendszerbe történő átírás kézenfekvő ábrázolási módja.
A helyiértékek a felírásban megfelelő sorrendben vannak.
A hiányzó helyiértékeket 0 értékekkel töltjük fel.
1 byte¶
A C nyelv szerinti unsigned char
típus. Más nyelvekben például u8
.
Nézzük meg a 94 érték ábrázolását!
[ 0 1 0 1 1 1 1 0 ]
7 6 5 4 3 2 1 0
Hexadecimális alakban: 5E
Ellenőrízzük, hogy valóban így történik a tárolás!
Tároljuk le egy fájlba az értéket!
Ellenőrízzük hexadecimális szerkesztővel!
Olvastassuk vissza az értéket!
Írjuk át (például
AB
-re)!Számoljuk ki, hogy milyen értéket várnánk!
Visszaolvasva ellenőrízzük, hogy valóban annyi lett!
Adat kiírása fájlba
#include <stdio.h>
int main(int argc, char* argv[])
{
FILE* file;
unsigned char value;
value = 94;
file = fopen("values.dat", "wb");
fwrite(&value, sizeof(value), 1, file);
fclose(file);
return 0;
}
Adat visszaolvasása fájlból
#include <stdio.h>
int main(int argc, char* argv[])
{
FILE* file;
unsigned char value;
file = fopen("values.dat", "rb");
fread(&value, sizeof(value), 1, file);
fclose(file);
printf("value = %u\n", value);
return 0;
}
2 byte¶
A C nyelv szerinti unsigned short
típus. Más nyelvekben például u16
.
Végezzük el az előző vizsgálatokat a 14274 érték esetén 2 byte-on!
Figyelem
A byte-ok sorrendje változhat a szerint, hogy litte- vagy big endian byte-sorrendről van-e szó!
4 byte¶
A C nyelv szerinti unsigned int
típus. Más nyelvekben például u32
.
Végezzük el az előző vizsgálatokat a 2966513 érték esetén 4 byte-on!
Figyelem
A C nyelv csak reláció szintjén adja meg, hogy egy-egy típusnak mennyi byte felel meg!
Ellenőrízzük sizeof
segítségével, hogy a vizsgált típusok mérete megfelelő!
#include <stdio.h>
int main(int argc, char* argv[])
{
printf("\nunsigned char : %d bit\n", (int)(8 * sizeof(unsigned char)));
printf("unsigned short : %d bit\n", (int)(8 * sizeof(unsigned short)));
printf("unsigned int : %d bit\n", (int)(8 * sizeof(unsigned int)));
printf("unsigned long : %d bit\n\n", (int)(8 * sizeof(unsigned long)));
printf("char : %d bit\n", (int)(8 * sizeof(char)));
printf("short : %d bit\n", (int)(8 * sizeof(short)));
printf("int : %d bit\n", (int)(8 * sizeof(int)));
printf("long : %d bit\n\n", (int)(8 * sizeof(long)));
printf("float : %d bit\n", (int)(8 * sizeof(float)));
printf("double : %d bit\n\n", (int)(8 * sizeof(double)));
return 0;
}
byte-ok száma |
előjel nélküli egész |
előjeles egész |
---|---|---|
1 |
|
|
2 |
|
|
4 |
|
|
8 |
|
|
Előjeles egész számok¶
Előjelbit használata¶
Kézenfekvő megoldásnak tünne.
Hogyan lenne használható?
Kettes komplemens ábrázolási mód¶
A kettes komplemens képzésének lépései:
Induljunk el a számjegyeken az alacsonyabb helyiértékektől a magasabbak felé. (Jobbról balra)
Másoljuk át az eredménybe a biteket az első 1-essel bezárólag.
A fennmaradó biteket negáljuk.
Tulajdonságai
A kettes komplemens képzést egymás után páros számú alkalommal végrehajtva mindig visszakapjuk az eredeti értéket.
Az MSB jelzi, hogy az érték negatív-e.
Példa
Ábrázoljuk a -20 értéket 1 byte-on, 2-es komplemens ábrázolási móddal!
[ 0 0 0 1 0 1 0 0 ]
7 6 5 4 3 2 1 0
Hexadecimális alak: 14
Kettes komplemens:
[ 1 1 1 0 1 1 0 0 ]
7 6 5 4 3 2 1 0
Hexadecimális alak: EC
Ellenőrízzük, hogy valóban így kerül tárolásra!
Példa
Ábrázoljuk a -1000 értéket 2 byte-on!
[ 0 0 0 0 0 0 1 1 1 1 1 0 1 0 0 0 ]
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Kettes komplemens:
[ 1 1 1 1 1 1 0 0 0 0 0 1 1 0 0 0 ]
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Hexadecimális alakban: FC18
Példa
Milyen értéket ábrázolnak az ACDC
hexadecimális alakban megadott byte-ok előjeles egész ábrázolási módot feltételezve?
[ 1 0 1 0 1 1 0 0 1 1 0 1 1 1 0 0 ]
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Az érték az MSB alapján negatív.
Kettes komplemens:
[ 0 1 0 1 0 0 1 1 0 0 1 0 0 1 0 0 ]
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Az ábrázolt érték a \(-5324_{(16)} = -21284\).
Egészes számábrázolási tartományok¶
byte-ok száma |
bitek száma |
előjel nélküli |
előjeles |
---|---|---|---|
1 |
8 |
\([0, 255]\) |
\([-128, 127]\) |
2 |
16 |
\([0, 65535]\) |
\([-32768, 32767]\) |
3 |
24 |
\([0, 2^{24}-1]\) |
\([-2^{23}, 2^{23}-1]\) |
4 |
32 |
\([0, 2^{32}-1]\) |
\([-2^{31}, 2^{31}-1]\) |
k |
\([0, 2^k-1]\) |
\([-2^{k-1}, 2^{k-1}-1]\) |
Alul- és túlcsordulás¶
Bitmintázatok és értékek 4 bit esetén.
bitminta |
előjel nélküli |
előjeles |
---|---|---|
0000 |
0 |
0 |
0001 |
1 |
1 |
0010 |
2 |
2 |
0011 |
3 |
3 |
0100 |
4 |
4 |
0101 |
5 |
5 |
0110 |
6 |
6 |
0111 |
7 |
7 |
1000 |
8 |
-8 |
1001 |
9 |
-7 |
1010 |
10 |
-6 |
1011 |
11 |
-5 |
1100 |
12 |
-4 |
1101 |
13 |
-3 |
1110 |
14 |
-2 |
1111 |
15 |
-1 |
Hogy ha kilépünk a számábrázolási tartományból (alul vagy felül) az nem feltétlenül jár hibajelzéssel.
Ilyen esetekben nem várt értékeket kaphatunk.
4 bit esetén, előjel nélküli esetben például ha 12-höz hozzáadunk 7-et, akkor 3-mat kapunk.
4 bit esetén, előjeles esetben, hogy ha például -5-ből kivonunk 7-et, akkor 4-et kapunk.
Az átviteli bitet a processzor kezeli (carry bit).
Törtek ábrázolása¶
Egészek formájában számlálóval és nevezővel¶
Megoldható, de általában nem praktikus.
Példa
Ábrázoljuk a \(\dfrac{45}{87}\) értéket úgy, hogy a számlálót és a nevezőt is előjel nélküli egész értékként kezeljük!
[ 0 0 1 0 1 1 0 1 0 1 0 1 0 1 1 1 ]
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
A tört értéke a 2D57
hexadecimális alakban megadott byte-okon ábrázolható.
Fix pontos ábrázolás¶
Rögzítjük, hogy mennyi bit-et szeretnénk az egész és a tört rész tárolására használni.
Példa
Tegyük fel, hogy 1 byte-on szeretnénk tört értékeket ábrázolni. A biteket a következőképpen csoportosítjuk (ebben a sorrendben):
1 bit előjel bit,
4 bit egészrész (előjel nélküli egészként),
3 bit törtrész.
Ábrázoljuk a -11,75 értéket!
[ 1 1 0 1 1 1 1 0 ]
7 6 5 4 3 2 1 0
Hexadecimális alakban a DE
byte-on ábrázolható.
Lebegőpontos ábrázolási mód¶
Normalizált szám
A számokat az egységes ábrázolás, majd későbbi tárolás érdekében egységes alakra hozzuk.
Például a \(-1,110101_{(2)} \cdot 2^{4}\) esetében
az előjel negatív,
a szignifikáns \(110101_{(2)}\),
a kitevő 4.
https://en.wikipedia.org/wiki/Significand
Szabvány
IEEE 754 szabvány, William Kahan, Berkeley Egyetem, 1985.
https://en.wikipedia.org/wiki/IEEE_754-1985
típus |
előjel |
eltolt kitevő |
szignifikáns |
összesen |
---|---|---|---|---|
egyszeres pontosság |
1 bit |
8 bit |
23 bit |
32 bit |
dupla pontosság |
1 bit |
11 bit |
52 bit |
64 bit |
A kitevő ábrázolásához a normalizált alakban szereplő kitevő kerül eltolásra:
egyszeres pontosság esetén 127-el,
dupla pontosság esetén 1023-mal.
A szabvány a normalizált számábrázolás mellett egyébb eseteket is megkülönböztet. Egyszeres pontosság esetén a következő formában.
előjel |
eltolt kitevő |
szignifikáns |
byte-ok |
jelentése |
---|---|---|---|---|
0 |
00000000 |
000…0 |
00 00 00 00 |
+0 |
1 |
00000000 |
000…0 |
80 00 00 00 |
-0 |
0 |
11111111 |
000…0 |
7F 80 00 00 |
\(+\infty\) |
1 |
11111111 |
000…0 |
FF 80 00 00 |
\(-\infty\) |
0 vagy 1 |
00000000 |
tetszőleges nem 0 |
denormalizált szám |
|
0 vagy 1 |
11111111 |
tetszőleges nem 0 |
NaN |
Denormalizált számok:
A nem tárolt bitet 0-nak tekintjük.
https://en.wikipedia.org/wiki/Subnormal_number
Példa
Ábrázoljuk a 119,6875 értéket egyszeres lebegőpontos számábrázolással!
Normalizált alak:
Kitevő: 6 \(\Rightarrow\) Eltolt kitevő: 6 + 127 = 133
[ 01000010 11101111 01100000 00000000 ]
Hexadecimális alakban: 42 EF 60 00
Tetszőleges pontosságú számábrázolás¶
Arbitrary Precision
Tulajdonképpen a számjegyeket tárolhatjuk.
Főként szimbólikus számítások esetében használják.
Kérdések¶
Számábrázolás esetén minek a rövidítése az MSB és az LSB?
Melyek azok az egész értékek, amelyek megegyeznek a kettes komplemensükkel?
Normalizált számábrázolás esetén egyszeres, és dupla pontosságú lebegőpontos számoknál milyen intervallumon változhat a kitevő?
Egyszeres pontosságú lebegőpontos számábrázolás esetén mennyi nem szám szimbólum van?
Adjunk példát olyan valós értékre, amely nem ábrázolható (pontosan) a szabványban megadott lebegőpontos számként!
Adjon példát (hexadecimális alakban) NaN értékre egyszeres lebegőpontos számábrázolás esetén!
Adja meg a \(-\infty\) értéket hexadecimális alakban, egyszeres lebegőpontos számábrázolást feltételezve!
Feladatok¶
Számjegyek számáról szóló tétel¶
Ha egy szám 61 jegyű kettes számrendszerben, akkor hány jegyű lesz 16 és 10-es számrendszerben?
Ha egy szám 9 jegyű 16-os számrendszerben, akkor hágy jegyű lesz 10-esben és kettesben?
Mennyi byte-on lehet ábrázolni a Neptun kódokat? Mi lenne, ha nem lennének benne számjegyek?
Tegyük fel, hogy egy mért értékről tudjuk, hogy az egy nemnegatív egész érték, és maximum \(10^{10}\) lehet az értéke. Legalább mennyi bit szükséges ahhoz, hogy biztosan ábrázolni tudjuk az előforduló értékeket?
Egészek ábrázolása¶
Ábrázoljuk az 5985-öt előjel nélküli egész számként 2, 3 és 4 byte-on! Az eredményt hexadecimális alakban adjuk meg!
Mennyi byte szükséges a -281, -512 és a -14890 értékek ábrázolásához?
Váltsuk át a 14889 és a -2488 számokat 2-es számrendszerbe!
Legalább mennyi bit szükséges az ábrázolásukhoz?
Adjuk össze őket 2-es számrendszerben!
Az összeget számoljuk vissza 10-es számrendszerbe, és ellenőrízzük!
Adjon példát olyan 4 byte-os egész számra, amely litte- és big endian ábrázolás esetében is ugyanolyan formában néz ki. Írja fel a hexadecimális alakot és az ábrázolt értéket!
Törtes ábrázolás¶
Törteket úgy szeretnénk ábrázolni, hogy a számláló 2 byte-os előjeles egész, a nevező pedig 2 byte-os előjel nélküli egész. (A nevező nem lehet 0. Egymást követő 2-2 byte-ról van szó.)
Melyik a legkisebb és a legnagyobb ábrázolható érték?
Mi lesz a legnagyobb ábrázolható negatív érték?
Milyen értéket ábrázolnak az
EC 81 00 3B
hexadecimális alakban megadott byte-ok?Milyen byte-okon ábrázolható (hexadecimális alakban felírva) a 0,03129 érték?
Melyik a legkisebb, 0-nál nagyobb ábrázolható érték?
Fix pontos ábrázolás¶
Törteket szeretnénk ábrázolni a következő séma szerint 2 byte-on:
1 előjelbit,
10 bit egészrész (előjel nélküli egészként),
5 bit törtrész.
(A részek ilyen sorrendben követik egymást.)
Válaszoljuk meg az alábbi kérdéseket!
Mennyi különböző értéket tudunk így ábrázolni?
Melyik a legkisebb és a legnagyobb ábrázolható érték? Hogyan néznek ki ezek a byte-ok hexadecimális alakban?
Melyik a legkisebb, 0-nál nagyobb ábrázolható érték? Hogyan néznek ki a byte-ok hexadecimális alakban?
Milyen értéket ábrázolnak az
F8 AC
byte-ok?
Az ábrázolási mód szerint össze szeretnénk adni a 31 0B
és a 0E 99
értékeket.
Mi lesz az eredmény byte-ok értéke hexadecimális alakban?
Hogyan ábrázolható a \(-\dfrac{3157}{32}\) érték?
Tegyük fel, hogy adott az E4 BB
érték fix pontos ábrázolás mellett.
Térjünk át egyszeres lebegőpontos ábrázolási módra, és adjuk meg az ábrázolás során kapott byte-ok értékét hexadecimális alakban!
Lebegőpontos értékek ábrázolása¶
Írjuk át a \(0,110101_{(2)}\), \(0,1201_{(3)}\) és a \(0,AB1E_{(16)}\) értékeket 10-es számrendszerbe!
Írjuk át a \(0.1\), \(0.15\) és \(0.625\) értékeket 2-es és 16-os számrendszerbe!
Vizsgáljuk meg a helyiértékes és a Horner-sémás átírást is!
Írjuk fel kettes számrendszerbe a következő értékeket!
Ellenőrízzük helyiértékesen és Horner sémával is!
Ábrázoljuk egyszeres lebegőpontos számábrázolással a következő értékeket!
Számítsuk ki, hogy milyen értékeket ábrázolnak a következő byte-ok egyszeres lebegőpontos ábrázolást feltételezve!
Ábrázoljuk egyszeres lebegőpontos számokként a következőket:
-51000.3046875, 0.9, 3.6, 4.78125, 3.141592 85EA0000, ABCD0000, FCA20000, 90909090
Adjuk meg a végtelen értékeket egyszeres pontossággal!
Egyszeres lebegőpontos számábrázolást feltételezve milyen értéket ábrázol a 7F801000?
Egyszeres pontossággal milyen értékeket ábrázolnak a következő byte-ok?
Töltsük ki az alábbi táblázatot!
duplaszó hexában |
|
|
|
előjel nélküli |
|||
előjeles |
|||
egyszeres lebegőpontos |
Szorozza meg az egyszeres pontosságú, lebegőpontos számként 9E CD 70 00
byte-okon ábrázolt értéket \(2^{70}\)-el! (Elegendő a hexadecimális alakot megadni végeredményként!)
Mennyivel áll több számjegyből a \(47^{23}\) érték 12-es számrendszerben felírt alakja, mint a \(25^{19}\) szám 9-es számrendszerben felírt alakja?