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:

Minden megoldásnak fordulnia kell c11 módban!

1. Lebegőpontos

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;
}

2. Emeletes tört

Írj programot, amely kiszámítja az alábbi tört valós (tizedestört) értékét! (−0.653333-et kell kapj).

                  4
4 + 2 − (3 − (6 + ─))
                  5
─────────────────────
        3(2−7)

3. Végtelen ciklus?

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;
}

4. Kettő hatványai, léptetéssel

Í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!

5. Egy szám bitjei

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.

6. Bitek titkai

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 & 65535
  • tömbelem = tömbelem & ~65535
  • tömbelem = tömbelem | 65535
  • tömbelem = tömbelem | ~65535
  • tömbelem = tömbelem ^ 65535
  • tö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.)

7. Rajzok

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!