Nincs találat
A keresett oldal nem található. Próbálja meg finomítani a keresést vagy használja a fenti navigációt, hogy megtalálja a bejegyzést.
A programozás egyik legizgalmasabb pillanata az, amikor a kódod végre gondolkodni kezd. Tud dönteni. Tud választani. Tud reagálni arra, amit a felhasználó (vagy éppen a világ) elé tesz. És pontosan ezt hozzák el nekünk a C++ feltételek: az if, az else, az else if és a logikai kifejezések.
Eddig már simán ment a számolás, változózás, műveletezés — de most lépünk át arra a szintre, ahol a programod elkezd valódi „intelligenciát” mutatni.
Igen, itt kezdődik az, amikor a kód „ha ez történik → akkor azt csináld” módba kapcsol.
Képzeld el úgy, mintha a programod kapna egy saját mini döntéshozó központot:
ha a felhasználó túl fiatal → „sorry, még nem vezethetsz”,
ha a szám pozitív → „minden oké, gyerünk tovább”,
ha az ugrás hosszabb, mint 8 méter → „wooow, díjazás jár!”.
A feltételek azok a kapuk, amelyek eldöntik, melyik irányba megy tovább a kódod — és hidd el, programozóként ezt az eszközt fogod a legtöbbször használni. Minden játék, minden alkalmazás, minden algoritmus tele van döntésekkel.
Ebben a leckében szépen, lépésről lépésre megnézzük:
hogyan működnek az if elágazások,
mikor kell else vagy else if,
hogyan írj tökéletes logikai kifejezéseket,
milyen tipikus hibákat érdemes elkerülni,
és hogyan gondolkodik valójában a számítógép egy feltétel kiértékelésekor.
Lesznek könnyű és instant megérthető példák, plusz néhány olyan mini feladat is, amitől érzed majd: „Oké… most már tényleg értem.”
A végére simán megoldod majd a nagyobb projektes feladatokat is (távolugrás, síugrás, lakásfeladat), hiszen azok tele vannak feltételes szerkezetekkel.
Na, csapjunk bele, mert ez az a rész, ahol a C++ elkezd igazán élőnek tűnni!
A feltétel (condition) tulajdonképpen egy kérdés, amit a program feltesz magának:
„Igaz ez… vagy hamis?”
Nincs harmadik opció.
A C++ itt nagyon „kocka módon” gondolkodik: vagy true, vagy false.
És attól függően, melyik a válasz, a program különböző „utakon” halad tovább. Ez olyan, mintha a kód egy kereszteződéshez érne:
Ha a feltétel igaz → akkor végrehajtja az adott utasítást.
Ha a feltétel hamis → akkor átugorja, vagy egy másik ágba lép.
Ezért hívjuk elágazásnak is.
A feltételt a legegyszerűbben az if kulcsszóval írjuk le.
Így kommunikálsz a géppel:
if (feltétel) {
//ezt csináld, ha igaz
}
A kis zárójelen belüli rész a lényeg – itt döntöd el, hogy milyen szabály alapján lépjen tovább a program. Például:
a > b → nagyobb-e az egyik szám a másiknál?
kor >= 18 → elmúlt-e a felhasználó 18 éves?
pont >= 50 → sikerült-e a vizsga?
ugras >= 8 → jár-e nagyobb díjazás a versenyzőnek?
Ha a feltétel igaz, a program belép a kapun. Ha hamis, fapofával sétál tovább a következő lehetőség felé. Nézzünk rá egy példát:
Az if szuper, amikor valamit csak akkor szeretnél lefuttatni, ha egy feltétel igaz. De mi van akkor, ha azt is szeretnéd megmondani a programnak, mi történjen, ha a feltétel hamis?
Na erre van az else.
Az else az a „különben” ág:
ha az if nem teljesül → az else fut le.
Ennyi. Tiszta sor.
💡 Úgy képzeld el, mint két út közötti kapcsolót:
if → ha páros a szám
else → ha NEM páros, tehát páratlan
Nincs másik opció. A szám vagy páros vagy páratlan, tehát az else mindig elkapja a fennmaradó esetet.
Nézzük egy szép, tiszta példával:
Az if és az else két helyzetet tudott megkülönböztetni: ha igaz -> ezt csináld, ha nem igaz > azt csináld.
De a valóságban kevés dolog fekete-fehér. Többnyire nem két, hanem több lehetséges eset is van. Itt lép a képbe az else if.
Az else if-nél a program tovább kérdez:
➡️ „Ha az első feltétel nem igaz, akkor nézzük meg ezt a másikat!”
➡️ „Ha ez se igaz, akkor még mindig van egy következő lehetőség…”
Így szépen, sorban, logikusan vizsgálja végig a különböző feltételeket.
Ha ezt írod neki:
if (feltétel)
utasítás1;
utasítás2;
akkor ő ezt így érti:
utasítás1 -> az if-hez tartozik
utasítás2 -> nem tartozik az if-hez, mindig lefut. A {} zárójelek nélkül az if CSAK EGY UTASÍTÁST fogad be. Amit beteszem a kapcsos zárójel közé, az egy utasításnak felel meg.
Példa:
if (szam > 0) std::cout << „Pozitiv szam” << std::endl;
Tehát, ha a szám nagyobb mint , akor futtasd le, hogy írja ki ez egy pozitív szám
Csakhogy ha hozzáírom még ezt a sort:
if (szam > 0) std::cout << „Pozitiv szam” << std::endl;
std::cout << „A szam nagyobb mint nulla” << std::endl;
Csak az első sor van hozzákötve az if-hez, a másodikat mindig lefuttatja. Így lesz helyes:
if (szam > 0) {
std::cout << „Pozitiv szam” << std::endl;
std::cout << „A szam nagyobb mint nulla” << std::endl; }
így mind a két sor ugyanahhoz az if-hez tartozik.
Előfordul, hogy egy feltétel csak akkor vizsgálható, ha egy másik már teljesült. Ilyenkor jönnek képbe a beágyazott if-ek. Ez olyan, mintha a program azt mondaná:
1. Nézzük meg az A-t
2. Ha A igaz, akkor vizsgáljuk meg a B-t is. Vagyis kétlépcsős döntést kell hozni.
Példa: a megadott szám pozitív és páros-e?
if (szam > 0) {
if (szam % 2 == 0) {
std::cout << „A szam pozitív és páros” << std::endl; }
else {
std::cout << ” A szam pozitív, de páratlan” << std::endl; }
else {
std::cout <<„A szam nem pozitív.” << std::endl;
}
Három lehetséges kimenet van:
Akkor érdemes beágyazott if-et használni, ha a második feltétel csak akkor értelmezhető, ha az első igaz. Például: ha a felhasználó be van jelentkezve, akkor ellenőrizzük, hogy adminisztrátor-e.
Ha nem kell beágyazni, a két feltétel egyszerre kell, hogy igaz legyen, akkor egyszerűbb így:
if (szam > 0 && szam % 2 == 0) {
std::cout << „A szám pozitív és páros” << std::endl; }
Csak akkor használunk beágyazott if-et, ha a vizsgálatoknak van egy sorrendje. Ha csak kombinálni akarod a feltételeket, akkor sokkal egyszerűbb a logikai operátor.
A keresett oldal nem található. Próbálja meg finomítani a keresést vagy használja a fenti navigációt, hogy megtalálja a bejegyzést.
Eddig már megtanultuk, hogyan tároljunk értéket változókban – most pedig megtanuljuk, hogyan számoljunk velük!
A C++ igazi ereje abban rejlik, hogy a memóriában tárolt értékekkel műveleteket tudunk végezni: összeadni, kivonni, osztani, hasonlítani, logikai döntéseket hozni.
Mielőtt komolyabb programokat írunk, fontos megérteni, hogyan működnek a kifejezések és az operátorok. Ezek azok az éptőkockák, amikből a programod döntései, számításai és feltételei felépülnek.
Minden kifejezés értékekkel és műveleti jelekkel dolgozik. Egy literál az a konkrét érték, amit leírsz a kódban
| Literál típusa | Példa | Jelentés |
|---|---|---|
| Szám literál | 5, -8, 3.14, 5e8 | Egész, negatív, tizedes és normál alakban írt számok |
| Karakter literál | ‘a’ | Egyetlen karakter (ASCII-ban tárolva) |
| Szöveg (string) literál | „szia” | Karakterek sora (string típus) |
| Logikai literál | true, false | Igaz vagy hamis érték |
Ezeket a literálokat vagy változókat kötjük össze operátorokkal – így jön létre a kifejezés (expression). Operandusoknak nevezzük azokat az elemeket, amiken az operátor dolgozik. Például az a + b kifejezésben a és b operandusok,a + pedig az operátor.
Kifejezésnek (expression) nevezünk bármilyen olyan C++ részt, amelynek van értéke. Például: 3 + 4, x * x, a+b/2.
Minden kifejezés valamit kiszámít, és az eredményt, értéket adja vissza.
Az operátor egy műveleti jel amely két vagy több operanduson dolgozik. Például? +, -, *, /, %
Ezeket matekból már ismered – csak itt a számítógép hajtja végre őket.
A C++-ban többféle operátor van:
| Operátor | Jelentése | Példa | Eredmény |
|---|---|---|---|
| + | összeadás | a + b | 5 + 8 = 13 |
| – | kivonás | a – b | 8 – 5 = 3 |
| * | szorzás | a * b | 5 * 8 = 40 |
| / | osztás | a / b | 5 / 8 = 0 (egész osztás) |
| % | maradékos osztás | a % b | 10 % 8 = 2 |
Ezeket a kifejezéseket már tanultad, amit azonban érdemes kiemelni: ha a és b egész típusú, akkor az osztás eredménye is egész lesz. Ezt megnéztük a változóknál bővebben, de mutatom, mire számíthatsz ilyen esetben:
Ha ezt beírod, az eredmény 0 lesz, mert az egész számok halmazán az 5-ben a 8 nullaszor van meg. Ahhoz, hogy pontosabb, tizedes eredményt kapj, az int helyett lebegőpontos típust kell használnod, például float-ot:
Ami esetleg új lehet, az % – maradékos osztás. Ez egész számokkal működik és az osztás maradékát adja vissza.
Ahogy a matekban is, itt is van műveleti prioritás. A szorzás és az osztás előrébb van, mint az összeadás és a kivonás. De lényegesen több operátort használunk, ezért több műveleti sorrendre is figyelni kell. A teljes műveleti sorrendet (precedence és associativity) itt találod:
🔗 cppreference.com – Operator precedence
Az asszociativitás azt mondja meg, hogy balról jobbra vagy jobbról balra értékelődik-e a művelet.
Ha felül akarod bírálni, itt is zárójeleket kell használni:
x = 5 + 3 * 2 -> x = 11
x = (5 + 3) * 2 -> x = 16
| Operátor | Jelentése | Példa | Eredmény |
|---|---|---|---|
| == | egyenlő | 8 == 10 | false |
| != | nem egyenlő | 8 != 10 | true |
| < | kisebb mint | 3 < 8 | true |
| > | nagyobb mint | 10 > 8 | true |
| <= | kisebb vagy egyenlő | 5 <= 5 | true |
| >= | nagyobb vagy egyenlő | 7 >= 8 | false |
A true = 1, a false pedig = 0-ként jelenik meg. Itt érdemes azt is megjegyezni, hogy a << kiíratás jele is egy operátor, aminek ráadásul a precedenciája magasabb, mint például a == -é. Ezért ez a művelet hibára fog futni:
Ilyenkor zárójelezzük, hogy az összehasonlítást végezze el
Nyilván a 10 nem egyenlő a 8 értékével, ezért ez az állítás hamis, azaz 0 lesz az eredmény.
Logikai értékeket kapcsolnak össze, például true / false típusokat. Nagyon fontosak lesznek majd az if feltételeknél.
| Operátor | Jelentése | Példa | Eredmény |
|---|---|---|---|
| ! | NEM (NOT) – megfordítja az igazságértéket | !(5 == 5) | false |
| && | ÉS (AND) – akkor igaz, ha mindkettő igaz | (3 > 1 && 7 < 10) | true |
| || | VAGY (OR) – csak akkor hamis, ha mindkettő hamis | (3 > 5 || 2 > 7) | false |
Pár megjegyzés hozzá: itt is fontos a zárójelezés, mert a << precedenciája magasabb, mint a logikai operátoroké
! előtag: bármi elé teheted, ami logikai értékre értékelődik, például: !(a == b)
&& – csak akkor igaz, ha mindkét oldal igaz. Ha az A hamis, akkor a B már nem számolódik ki
|| – csak akkor hamis, ha mindkét oldal hamis. Ha az A igaz, akkor a B már nem számolódik ki
| A | B | A && B |
|---|---|---|
| false | false | false |
| false | true | false |
| true | false | false |
| true | true | true |
| A | B | A || B |
|---|---|---|
| false | false | false |
| false | true | true |
| true | false | true |
| true | true | true |
| A | !A |
|---|---|
| false | true |
| true | false |
| Operátor | Jelentése | Példa | Magyarázat | Eredmény |
|---|---|---|---|---|
| = | egyszerű értékadás | a = b; | a értéke felveszi b aktuális értékét (a felülíródik) | ha b = 10 → a = 10 |
| += | hozzáadás és értékadás | x += 3; | rövidítés az x = x + 3 formára |
ha x 5 volt → x = 8 |
| -= | kivonás és értékadás | x -= 2; | rövidítés az x = x - 2 formára |
ha x 8 volt → x = 6 |
| *= | szorzás és értékadás | x *= 2; | rövidítés az x = x * 2 formára |
ha x 6 volt → x = 12 |
| /= | osztás és értékadás | x /= 3; | rövidítés az x = x / 3 formára |
ha x 12 volt → x = 4 (egész osztásnál) |
Néhány megjegyzés hozzá:
Az értékadás asszociativitása jobbról balra halad, azaz a = b = 10-nél először a b = 10, majd az a = 10.
A bal oldalnak írhatónak kell lennie, literálnak nem lehet értéket adni.
Típuseltérésekél konverzió történik: double d = 3.5; int x = 0; x = d -> x 3 lesz, a tört rész levágódik.
| Forma | Jelentése | Példa | Egyenértékű hosszú alak | Hatás a változóra |
|---|---|---|---|---|
| ++x | növelés eggyel (prefix) | ++b; | b = b + 1; (ugyanaz, mint b += 1) | b értéke azonnal nő |
| x++ | növelés eggyel (postfix) | b++; | b = b + 1; | b nő, de a kifejezés **régi** értéket ad vissza |
| –x | csökkentés eggyel (prefix) | –b; | b = b – 1; (ugyanaz, mint b -= 1) | b értéke azonnal csökken |
| x– | csökkentés eggyel (postfix) | b–; | b = b – 1; | b csökken, de a kifejezés **régi** értéket ad vissza |
Mit jelent a prefix – postfix a gyakorlatban?
int x = 5
int y = ++x //prefix
1. lépés: ++x -> növeli x-et hatra
2. lépés: az új értéket (6) adja vissza
3. lépés: y megkapja az új értéket (6)
-> tehát x=6, y=6
Most ugyanez postfix-szel:
int x = 5;
int y = x++ //postfix
1. lépés: előbb visszaadja a régi értéket (5)
2. lépés: növeli az x-et hatra
3. lépés: y az eredeti 5-öt kapja meg
-> tehát x=6, y=5
Ha növelni akarod a változót, akkor mindegy, melyiket használod, de ha kifejezésben szerepel, akkor nem.
Ha x = 5
y = x++ + 2; -> y = 7, x = 6
y = ++x + 2 -> y = 8, x = 6
1. Műveletek gyakorlása: írj egy programot, ami két számot bekér, majd kiírja:

2. Írj egy programot, ami két számról megmondja, hogy:

3. Prefix és postfix közti különbség: magyarázd el, mit kapsz és miért?

4. Mennyi lesz az eredmény és miért? (műveleti sorrend)
Először a 2+5 számolódik ki, az 7, majd a *= értékadás. 
5. Logikai gyakorlás. Írd le, miért 1 vagy 0 az eredmény:
a – igaz
b – hamis – innen indul a logikai műveletünk
!a -> ha a igaz, akkor az a hamis lesz. Ekkor hamis || hamis ->az eredmény hamis. Kimenet: false
(a && !b) > mivel a b hamis, a !b igaz lesz. A igaz és B igaznál az egész kifejezés igaz.
6. Mi lesz az eredmény és miért?
int a = 5 / 2;
float b = 5 / 2;
float c = 5 / 2.0
float d = 5.0 / 2;
float e = (float)5/2;
1. – mindkét operandus, az 5 és a 2 egész szám (int) Egész számoknál a C++ levágja a tizedes részt.
2. float a változó, de a művelet két int között zajlik. Kiszámolja az osztást egész osztásként és csak az eredményt alakítja át float típusra
3. Az egyik operandus lebegőpontos, a másik operandust automatikusan előrelépteti lebegőpontos típusra
4. ugyanaz az eset, csak a másik oldal a lebegőpontos
5. Itt te kényszeríted az első operandust lebegőpontos típusra.
A keresett oldal nem található. Próbálja meg finomítani a keresést vagy használja a fenti navigációt, hogy megtalálja a bejegyzést.
A számítógépek világa tele van különleges logikával – és a fixpontos számrendszerek pont egy olyan téma, ami elsőre bonyolultnak tűnhet, de valójában nagyon izgalmas!
Ebben a leckében anime-lány kalauzunk segít megérteni, hogyan működnek ezek a rendszerek: mit jelent a tizedespont helye,
hogyan határozza meg a számok pontosságát, és miért különböznek a lebegőpontos formátumtól. Lépésről lépésre haladunk, ábrákkal, példákkal – hogy a fixpontos számrendszerek érthetőek legyenek
Képzeld el, hogy egy számot szeretnél ábrázolni a számítógépben.
Ehhez a gép bitjeit (0-kat és 1-eket) használja, és a legfontosabb kérdés az, hol legyen a tizedespont.
A fixpontos számrendszerben ez a pont fix helyen van – azaz előre megmondjuk, hány bit tartozik az egész részhez, és hány a törtrészhez.
Innen jön a neve is: fixed-point, vagyis rögzített tizedespontú.
Ez különbözik a lebegőpontos rendszertől, ahol a pont helye változhat (azaz lebeg), és ezért sokkal nagyobb számokat is tudunk ábrázolni – de bonyolultabban.
A fixpontos számrendszerekkel ugyanúgy végezhetünk összeadást és kivonást, mint a sima egész számokkal – hiszen a bitműveletek megegyeznek.
De ha szorzást vagy osztást végzünk, figyelni kell a tizedespont helyére, mert az elmozdulhat.
Ez azért fontos, mert a végeredményben más lehet az egész–tört arány, mint amit eredetileg kijelöltünk.
Ez a képlet az előjeles, bináris fixpontos szám értékét adja meg. Nézzük meg részletesen, mit jelent:
bN−1 -> az utolsó (legmagasabb helyiértékű bit, amit előjelbitnek nevezünk. Ha ez a szám 0, akkor a szám pozitív, ha 1, akkor a szám negatív.
N -> teljes bithossz, azaz hány bitből áll a szám, például 8 vagy 16
p -> a tizedespont helye, azaz hány bit tartozik a törtrészhez
2^i-p -> ez mutatja meg, hogy az adott bit milyen helyiértéket képvisel.
A képlet tehát nem más, mint a szám bináris helyiértékeinek összege – figyelembe véve az előjelet és a tizedespont helyét.
Van az a pillanat, amikor a matek kicsit olyan, mint egy makacs rokon: nem szeret változtatni a helyén.
A fixpontos számrendszerek pontosan ilyenek — itt a tizedespont egyszerűen nem mozdul.
Mindig ugyanott van, akkor is, ha a világ összeomlik körülötte.
És bármilyen hihetetlen, ennek a „makacsságnak” komoly technológiai előnyei vannak.
A számítógép minden számot bitek sorozataként tárol. Ha ezek egész számok, akkor egyszerű: minden bit egy-egy hatvány a kettes számrendszerben.
De mi van, ha törteket is szeretnénk tárolni? Valahol el kell helyezni a tizedespontot (vagy binárisban: radix point).
A fixpontos számrendszerben ez a pont előre meghatározott helyen van.
Mondjuk például: „a 16 bitből 8 az egész rész, 8 a törtrész”. Innentől kezdve nincs vita: minden számot ebben a formában kell értelmezni. Így néz ki például egy 16 bites fixpontos formátum (p = 8):
S EEEEEEE.FFFFFFFF | | | | | | +---------> 8 bit a törtrész | +---------------> 7 bit az egész rész +-------------------> előjelbit
Mert gyors.
A számítógép nem kell, hogy újra és újra kiszámolja, hová kell „tennie” a tizedespontot, mint a lebegőpontos műveleteknél.
A fixpontos forma sokkal egyszerűbb logikát igényel – és ez az egyszerűség értékes az olyan eszközöknél, ahol kevés az erőforrás: mikrokontrollerek, DSP-k, jelfeldolgozás, beágyazott rendszerek.
Ráadásul kis tartományban sokkal stabilabb és pontosabb, mint a lebegőpontos számok.
Ha például hangot vagy képet dolgozol fel, nem akarsz lebegő tizedespontokat, csak egy kis, precíz fix skálát.
A fixpontos számrendszer egyik kulcsfogalma a Δr, azaz a differencia vagy felbontás.
Ez azt mutatja, mennyi a különbség két egymást követő szám között.
Ha p = 8, akkor:
Ez azt jelenti, hogy a legkisebb „ugrás” a számok között kb. 0,0039.
Olyan ez, mintha a mérleged nem grammokat, hanem csak 4 grammos lépésekben mérne — nem rossz, csak tudni kell, hogy mennyire „durván” mérsz.
Legyen egy 16 bites fixpontos rendszer, ahol:
N = 16 bit
p = 8 bit (törtrész)
előjeles (2’s complement) formátumot használunk
Ez azt jelenti: 1 bit az előjelre, 7 bit az egész részre, 8 bit a törtrészre jut.
| Jelölés | Bináris alak | Érték | Magyarázat |
|---|---|---|---|
| V(zéró) | 00000000.00000000 |
0.0 | a nullapont |
| V(legkisebb pozitív) | 00000000.00000001 |
1/256 = 0.00390625 | a legapróbb pozitív érték |
| V(legnagyobb pozitív) | 01111111.11111111 |
128 − 1/256 = 127.99609375 | az utolsó pozitív szám a tartományban |
| V(legkisebb negatív) | 10000000.00000000 |
−128 | a legnagyobb negatív érték |
| V(legnagyobb negatív) | 11111111.11111111 |
−1/256 = −0.00390625 | a nullához legközelebbi negatív érték |
Ha ránézel a számokra, rögtön feltűnik, hogy a tartomány −128 és +127.996 között van.
És felmerül a kérdés:
„Miért nem −128 és +128?”
Teljesen jogos.
A válasz az előjelbit.
A fixpontos, előjeles bináris számok kétkomplementes formában működnek.
Ez azt jelenti, hogy az első (bal szélső) bit nem számértéket, hanem előjelet jelöl:
0 → pozitív szám,
1 → negatív szám.
Ettől viszont a tartomány egy kicsit félrebillen.
A pozitív oldalon az egyik kombináció (amikor minden bit 1 lenne) „átcsúszna” a negatív tartományba, ezért onnan egy szám hiányzik.
💬 Összefoglalva:
A legnagyobb negatív szám (−128) teljes egészében lefedett,
a legnagyobb pozitív pedig egy hajszállal kisebb (+127.996).
Nem hiba – ez a kétkomplementes kódolás természetes velejárója.
Ez az egész történet lényege.
A „pont” nem egy tényleges karakter, nem tárolódik a memóriában.
A számítógép nem jegyzi meg, hova tettük a pontot – csak tudja, hogy hol kell képzeletben lennie.
Ha például azt mondjuk:
„Ez egy 16 bites fixpontos szám, amiben 8 bit a törtrész”,
akkor a gép automatikusan úgy értelmezi, hogy a tizedespont 8 bit után van a jobbról számolva.
Ez a fixpontos rendszerek legfontosabb szabálya:
a pont nem mozdulhat, mert ez az egész ábrázolás stabilitását adja.
💬 Gyakorlati példa:
Ha ugyanazt a 16 bitet másként értelmezed (mondjuk 4 bit törtrész, 12 egész), akkor a szám teljesen más értéket adna.
Ezért fix, mert a program és a hardver közösen megegyeznek a helyéről.
Minél több bitet adsz a törtrészhez, annál pontosabban tudod kifejezni a számokat —
de közben kevesebb hely marad az egész részre.
Ha kevesebb bit a törtrész, akkor nagyobb számokat tudsz ábrázolni, de kevésbé részletesen.
Ez egy kompromisszum, amit minden mérnöknek meg kell kötni.
Olyan ez, mint a fényképeknél a felbontás:
ha túl nagyra nagyítasz, elveszik a részlet;
ha túl kicsire méretezel, minden pixeles lesz.
Példa:
p = 8 → 1/256-os pontosság, tartomány kb. −128…+127.996
p = 4 → 1/16-os pontosság, tartomány kb. −2048…+2047.9375
💬 Vagyis:
A pontosság mindig az ár, amit a nagyobb tartományért fizetsz.
Jogos kérdés.
A lebegőpontos számok sokkal „rugalmasabbak” – a tizedespont helye változhat, így hatalmas tartományt fedhetnek le.
A kérdés viszont: mindenáron kell az a rugalmasság?
A válasz legtöbbször: nem.
A fixpontos számrendszereknek két hatalmas előnyük van:
Sebesség.
Egy mikrokontroller, ami például egy robotkart irányít, nem akar lebegőpontos számokat tologatni.
Az drága művelet, sok energiát és időt igényel.
A fixpont viszont azonnal működik, mert egyszerű egész műveleteket végez.
Kiszámíthatóság.
A fixpontos műveletek mindig ugyanazt az eredményt adják, nincs „kerekítési meglepetés”, mint a lebegőpontos világban.
Mi az az endianitás? Az endianitás lényege, hogy meghatározza, milyen sorrendben tárolja és olvassa ki a számítógép a több byte-ból álló adatokat.Másképp fogalmazva: amikor a gép elment egy számot, eldönti, melyik byte kerüljön előre és melyik hátra – ez alapján fogja...
Tudod mi történik a számítógép belsejében, amikor megnyomsz egy gombot?A számítógép felépítése megmutatja, hogyan dolgozik együtt a hardver, a szoftver és az adatok, hogy minden működjön. Ebben a leckében felfedezzük, miből áll a gép, hogyan kommunikálnak az...
Minden informatikai feladat ugyanúgy indul: van egy probléma, amit meg kell oldanunk. De hogyan lesz ebből működő program? A probléma - algoritmus - program lépéssor az informatika gondolkodásának alapja - itt tanulod meg, hogyan gondolkozik a gép, és hogyan tudsz te...
Az előző leckében már megtanultuk, hogyan működik a 2’s komplemens,
és azt is láttuk, hogy ez a módszer teszi lehetővé, hogy a számítógép kivonást is összeadással tudjon elvégezni.
(Aki lemaradt róla, itt tudja bepótolni 👉 Kettes komplemens – avagy hogyan gondolkodik a gép a negatív számokról)
Most tovább megyünk, és megnézzük, hogyan használja ezt a rendszer a gép az előjeles számok ábrázolására.
Ettől lesz igazán „emberi logikájú” a számítógép aritmetikája:
a legelső bit (MSB) jelzi az előjelet, miközben a többi bit helyiértékként viselkedik.
Itt jön képbe az előjeles 2’s komplemens rendszer,
ami már nem csak a műveletek egyszerűsítéséről szól, hanem a negatív számok értelmezéséről is.
A számítógép minden számot bitek sorozataként tárol.
Egy 8 bites példában például így nézhet ki egy szám: 01001110
Ebben minden bitnek van helyiértéke, ahogy a tizes számrendszerben is van egyese, tizese százas helyiértéke. A binárisban a helyiértékek a 2 hatványai:
a legkisebb (jobboldali) bit az 2⁰,
a következő 2¹,
aztán 2², 2³, és így tovább.
A bal szélső bit (a legnagyobb helyiértékű) az úgynevezett
➡️ MSB – Most Significant Bit, azaz a legnagyobb helyiértékű bit.
És itt jön a lényeg:
a 2’s komplemens rendszerben ez a legelső bit jelöli az előjelet.
Ha az MSB = 0, akkor a szám pozitív.
Ha az MSB = 1, akkor a szám negatív.
Például: 01001110₂ = +78₁₀, 11001110₂ = -50₁₀
A különbség mindössze az első bit, mégis teljesen más a jelentése!
A gép ebből az egyetlen jelből tudja, hogy az értéket a 2’s komplemens logika szerint kell értelmeznie.
| Bitminta | Érték | Megjegyzés |
|---|---|---|
| 01111111 | 127 | Legnagyobb ábrázolható érték. |
| 01111110 | 126 | |
| 01111101 | 125 | |
| … … … | ||
| 00000010 | 2 | Kezdő nulla → pozitív szám. |
| 00000001 | 1 | |
| 00000000 | 0 | A nulla egyedi ábrázolása. |
| 11111111 | −1 | A −1 mindig „csupa 1”. |
| 11111110 | −2 | Kezdő egyes → negatív szám. |
| 11111101 | −3 | |
| … … … | ||
| 10000010 | −126 | |
| 10000001 | −127 | |
| 10000000 | −128 | Legkisebb (legnegatívabb) ábrázolható érték. |
Mi az az endianitás? Az endianitás lényege, hogy meghatározza, milyen sorrendben tárolja és olvassa ki a számítógép a több byte-ból álló adatokat.Másképp fogalmazva: amikor a gép elment egy számot, eldönti, melyik byte kerüljön előre és melyik hátra – ez alapján fogja...
Tudod mi történik a számítógép belsejében, amikor megnyomsz egy gombot?A számítógép felépítése megmutatja, hogyan dolgozik együtt a hardver, a szoftver és az adatok, hogy minden működjön. Ebben a leckében felfedezzük, miből áll a gép, hogyan kommunikálnak az...
Minden informatikai feladat ugyanúgy indul: van egy probléma, amit meg kell oldanunk. De hogyan lesz ebből működő program? A probléma - algoritmus - program lépéssor az informatika gondolkodásának alapja - itt tanulod meg, hogyan gondolkozik a gép, és hogyan tudsz te...
A számítógépek nem „tudják”, mi az, hogy negatív szám.
A gép szemében minden csak 0 és 1, vagyis bináris logika.
A kérdés tehát az: hogyan lehet egy ilyen rendszerben azt kifejezni, hogy –5?
Erre ad zseniális megoldást a 2’s komplemens.
Az előző részben megismertük, hogyan egészítjük ki a számokat úgy, hogy minden helyiértéken elérjük a maximumot – ez volt a p−1’s komplemens elve.
Most jön a trükk, amitől a számítógép tényleg életre kel: a p’s komplemens, vagyis a 2’s komplemens a bináris világban.
A 2’s komplemens tulajdonképpen a „felturbózott” verzió: mindössze annyit csinálunk, hogy a korábban kapott komplemenshez hozzáadunk +1-et. És ezzel elérjük, hogy a számítógép a kivonást is egyszerű összeadással végezze el – villámgyorsan és hibamentesen.
Ez az apró lépés, a +1 hozzáadása, egy teljes logikai áttörés volt: mostantól a gép nem „külön gondolkodik” a negatív számokról, hanem egyszerűen ugyanazt az áramkört használja hozzá, mint az összeadáshoz. Így a kivonás = komplemens + 1 + összeadás.
A következő példában látni fogjuk, hogyan számol a gép a 2’s komplemens segítségével, és mit jelent valójában az a kis „túlcsorduló” 1, ami látszólag eltűnik – pedig ez teszi lehetővé, hogy a bináris világban minden érték „körbeérjen”.
Az előző leckében már megtanultuk, hogyan működik a p’s komplemens a 10-es számrendszerben — ott a „+1 trükk” segített abban, hogy a kivonás egyszerűen összeadássá váljon. Most ugyanezt az elvet nézzük meg binárisan, azaz a 2-es számrendszerben.
A különbség mindössze annyi, hogy:
a 10-es rendszerben a „p” = 10,
a binárisban pedig „p” = 2.
Vagyis most már a 2’s komplemensről beszélünk.
A bináris számrendszerben minden bitet megfordítunk:
a 0-ból 1 lesz,
az 1-ből pedig 0.
Ez az úgynevezett 1’s komplemens. Ha ehhez hozzáadunk +1-et, akkor megkapjuk a 2’s komplemenst – vagyis azt a formát, amivel a gép a negatív számokat is tudja kezelni és a kivonást is egyszerűen elvégzi.
Vegyünk egy 8 bites bináris számot, például:
0011 0001₂
Ez a szám pozitív, és decimálisan 49₁₀-et jelent.
A bináris 1’s komplemens egyszerűen azt jelenti, hogy minden bitet megfordítunk:
ahol 0 volt, ott 1 lesz,
ahol 1 volt, ott 0 lesz.
Tehát:
Eredeti: 0011 0001
Komplemens: 1100 1110
Ez a művelet bitenkénti negálás (invertálás).
A következő lépésben a gép egyet hozzáad ehhez az 1’s komplemenshez:
1100 1110
+ 1
──────────
1100 1111
Ez már a 2’s komplemens, vagyis a bináris „negatív párja” az eredeti számnak.
Ha a gép ezt a formát látja, tudja, hogy a szám negatív, és a számértéket ebből fogja kiszámolni.
A kettes komplemens tulajdonképpen azt mondja:
„Egészítsd ki a számot a következő bináris alapig, azaz 2ⁿ-ig.”
8 bit esetén ez: 2⁸ = 256
Ha az eredeti szám 49, akkor a 2’s komplemens (a „negatív párja”) 256 − 49 = 207 lesz,
vagyis a gép így reprezentálja a −49-et.
Ha összeadod az eredeti és a kettes komplemens alakot, mindig megkapod a teljes „kört”:
0011 0001
+ 1100 1111
──────────
1 0000 0000
Az 1 „túlcsordul”, vagyis kiesik, és a 8 bites helyen marad: 0000 0000. Ez pontosan a bináris nullát jelenti – a rendszer tehát bezárult, visszatért a nullához.
Számoljuk ki a 43₁₀ kettes komplemensét.
1. lépés: Megnézem, hogy negatív számról van-e szó. Nem negatív, tehát átkonvertálom bináris számrendszerbe és úgy hagyom, mert a pozitív szám kettes komplemense önmaga.
Eredmény: 43₁₀ = 00101011₂
Számoljuk ki a −123₁₀ kettes komplemensét.
1. lépés: Ez most negatív szám, tehát végig kell csinálnunk a 2’s komplemens lépéseit. Ehhez 8 bitet használunk (mert ez a leggyakoribb fix hossz).
2. lépés: Elhagyjuk az előjelet és átkonvertáljuk a szám abszolút értékét binárisra: 123₁₀ = 01111011₂
3. lépés: Minden bitet megfordítunk (1’s komplemens): 01111011 → 10000100
4. lépés: Hozzáadunk +1-et (2’s komplemens): 10000100 + 1 = 10000101
Eredmény: −123₁₀ = 10000101₂
A 2’s komplemens eljárás azért zseniális, mert így a gép nem külön kezeli a negatív számokat.
Az 10000101₂ értéke a gép számára automatikusan −123 lesz, mert az első bit (a legbaloldalibb) 1, tehát ez egy negatív szám — a rendszer pedig a 2’s komplemens szabály szerint dekódolja.
1. feladat Számoljuk ki a 67₁₀ kettes komplemensét!
1. lépés: Ellenőrizzük, negatív-e a szám. Nem — tehát egyszerűen binárisra váltunk.
2. lépés: Átváltás binárisra (8 bites): 67₁₀ = 01000011₂
3. lépés: Pozitív szám, így a kettes komplemense önmaga.
👉 Eredmény: 67₁₀ = 01000011₂
2. feladat: Számoljuk ki a –58₁₀ kettes komplemensét!
1. lépés: Ez negatív szám, tehát végig kell csinálnunk az eljárást.
2. lépés: Átváltás abszolút értékre: 58₁₀ = 00111010₂
3. lépés: 1’s komplemens → bitek megfordítása: 11000101₂
4. lépés: +1 hozzáadása (2’s komplemens): 11000101₂ + 1₂ = 11000110₂
👉 Eredmény: –58₁₀ = 11000110₂
3. feladat: Számoljuk ki a –103₁₀ kettes komplemensét!
1. lépés: Negatív szám, tehát teljes eljárás kell.
2. lépés: Átváltás abszolút értékre: 103₁₀ = 01100111₂
3. lépés: 1’s komplemens → bitek megfordítása: 10011000₂
4. lépés: +1 hozzáadása: 10011000₂ + 1₂ = 10011001₂
👉 Eredmény: –103₁₀ = 10011001₂
Mi az az endianitás? Az endianitás lényege, hogy meghatározza, milyen sorrendben tárolja és olvassa ki a számítógép a több byte-ból álló adatokat.Másképp fogalmazva: amikor a gép elment egy számot, eldönti, melyik byte kerüljön előre és melyik hátra – ez alapján fogja...
Tudod mi történik a számítógép belsejében, amikor megnyomsz egy gombot?A számítógép felépítése megmutatja, hogyan dolgozik együtt a hardver, a szoftver és az adatok, hogy minden működjön. Ebben a leckében felfedezzük, miből áll a gép, hogyan kommunikálnak az...
Minden informatikai feladat ugyanúgy indul: van egy probléma, amit meg kell oldanunk. De hogyan lesz ebből működő program? A probléma - algoritmus - program lépéssor az informatika gondolkodásának alapja - itt tanulod meg, hogyan gondolkozik a gép, és hogyan tudsz te...