Labor, 11. hét: számábrázolás
Pohl László, Czirkos Zoltán · 2025.11.14.
Számábrázolási kérdések és bitműveletek.
Felkészülés a laborra:
- Az operátorokról tanultak átismétlése, a számábrázolásról tanultak megértése.
- A bitműveletek feltétlenül szükségesek a feladatokhoz.
Minden megoldásnak fordulnia kell c11 módban!
Mit írnak ki az alábbi program egyes sorai? Próbáld meg kitalálni! Futtasd le a programot, és magyarázd meg az eredményt!
A printf() %g formátumsztringje azt jelenti, hogy mindig a legrövidebb kiírási
formát használja – ha a normálalak rövidebb, akkor azt.
#include <stdio.h>
#include <math.h>
int main(void) {
printf("1. %f\n", 1.23456789123456789123456789e40);
printf("2. %g\n", 1e40);
printf("3. %s\n", 1e3+1 == 1e3 ? "igaz" : "hamis");
printf("4. %s\n", 1e30+1 == 1e30 ? "igaz" : "hamis");
printf("5. %g\n", pow(10, 40) / pow(10, -40));
printf("6. %g\n", powf(10, 40) / powf(10, -40));
return 0;
}
Az alábbi program egy olyan ciklust tartalmaz, mely addig fut, amíg egy minden iterációban megnövelt szám pozitív marad.
Matematikailag ez nyilvánvalóan végtelen ciklus. No de mi a helyzet a gyakorlatban? Próbáld ki int és short
int, signed char típussal is! Magyarázd meg a jelenséget! Miért pont azok a számok jelentek meg, amiket
látsz?
#include <stdio.h>
int main(void) {
int i = 1;
while (i > 0) {
++i;
}
printf("%d\n", i);
return 0;
}
Írj programot, amelyik kiszámítja a 2 első 32 hatványát, a 20-tól indulva!
Használd ehhez a léptető << operátort! Mit tapasztalsz, ki tudod írni
a 2 első 40 hatványát is?
Ezek után módosítsd úgy a programodat, hogy egy unsigned int típusú
változó értékét változtasd benne, mindig eggyel balra léptetve a <<=
operátorral! Az előző feladat tapasztalatából kiindulva, a ciklust futtathatod addig, amíg
a változó túl nem csordul – nem fixen 32 iterációval.
Ezek alapján olyan programot is lehetne írni, amelyik egy adott típusról megmondja, hogy
hány bites: addig kell léptetni, amíg túl nem csordult. Módosítsd úgy a programot, hogy
képes legyen megszámolni egy előjel nélküli egész változó bitjeinek számát, más néven
szóhosszúságát! Mekkora egy unsigned char, egy unsigned short int,
egy unsigned int, egy unsigned long int, és egy unsigned long long int
a gépen, amelyiken dolgozol? Figyelj a fordító hibaüzeneteire, a printf() paraméterezését
módosítani kell majd az egyes típusoknál!
Dolgozz tovább abból a feltételezésből kiindulva, hogy a gépeden az unsigned long int típus
32 bites. Írj egy olyan programrészletet, amelyik egy ilyen típusú változóban tárolt szám bitjeit
kiírja! Pl. 29 esetén ez a bitminta 00000000000000000000000000011101,
mert
29 = 1×24+1×23+1×22+0×21+1×20,
azaz 2910 = 111012.
Tipp
Emlékezz vissza, a >> operátorral tudsz jobbra léptetni egy számot. Ha kíváncsi vagy valamelyik
bitjére, akkor annyiszor lépteted jobbra, ahányadik bit az érdekes – utána pedig a bitenkénti ÉS operátorral kivágható a legalsó bit.
Az előző feladat folytatása: a bitenként kiíró programodat írd át úgy, hogy az 1-esek helyére
'#' karaktert, a 0-k helyére ' ' (szóköz) karaktert tegyen!
(Ehhez használhatod a ?: operátort is.)
Utána pedig úgy, hogy ne csak egy szám bitmintáját írja ki ilyen formában, hanem az alábbi tömb összes számát, egymás alá! Mit látsz?
unsigned long szamok[8] = { 0U, 1931988508U, 581177634U, 581374240U,
581177632U, 581177634U, 1919159836U, 0U };
Ha megvan, amit látni kell, akkor próbáld ki, hogy a kirajzolás előtt az összes tömbelemet megváltoztatod az alábbi módokon:
tömbelem = tömbelem & 65535tömbelem = tömbelem & ~65535tömbelem = tömbelem | 65535tömbelem = tömbelem | ~65535tömbelem = tömbelem ^ 65535tömbelem = tömbelem ^ ~65535
Magyarázd meg a kapott eredményeket! (Segít, ha megvizsgálod a 65535 és a ~65535 bitmintáját is előbb.)
Az előző feladat tömbje egy fekete-fehér rajzot tárolt a számokban. Ebben a feladatban ezt kell továbbfejlesztened.
Hozz létre egy 32×24 pontból álló rajzot, és dolgozz azon! A rajz szélessége (32) az unsigned long int
méretéből adódik; a magasság (24) a tömbméretből. A konzolablak 24 vagy 25 sor magas szokott lenni, így el fog férni a rajzod.
Írj programrészt, amelyik:
- Letörli a rajzot, azaz mindegyik bitet „feketévé”, 0-vá változtatja!
- Rajzol egy pontot, azaz „fehér”, 1-es bitet tesz egy adott (x, y) pozícióra!
Készíts a fentiek használatával egy rajzot! Rajzolj pl. kört vagy téglalapot, vagy egyéb formát!