Ez a szekció lehetővé teszi a felhasználó által írt összes hozzászólás megtekintését. Vedd figyelembe, hogy csak azokba a fórumokba írt hozzászólásokat látod, amelyekhez hozzáférésed van.
Üzenetek - tonyo
Oldalak: 1 ... 37 38 [39] 40 41 ... 79
571
« Dátum: 2012. augusztus 01. - 18:27:12 »
Külföldi VPS. Mivel VPS alapból gyengébb, mint egy rendes szerver. És mivel külföldi, így alapból magasabb a pinged is.
572
« Dátum: 2012. augusztus 01. - 13:27:44 »
A Clans.hu-t tegnap DDoS támadás érte. Jelenleg nem mûködik még tökéletesen minden, szelektíven jön be a web is(nálam pl. mûködik, és sokaknál, de másoknál meg nem). Dolgoznak a problémán.
Hú, valaki nagyon beszólt Megyek sírni a sarokba. Mellesleg ügyes vagy, csak a helyedben átolvasnám még a fórum szabályzatot. Nem tudom mi köze ennek a hihetetlen poénnak a szerverhez, amit egy olyan valaki talált ki, aki hirtelen nagyon nagy fiú lett, miután töröltem magam PDRP webrõl
573
« Dátum: 2012. augusztus 01. - 11:41:49 »
Tegnap este nem jött be a web senkinek, de már újra jó
574
« Dátum: 2012. augusztus 01. - 11:39:35 »
Amúgy énmég erre figyeltem fel, hogy ezt még elírtad. -2^32(-2,147,483,648) és 2^32-1(2,147,483,647) Csak a 31.-en, mivel nem elõjel nélküli.
Igazad van, köszönöm a jelzést, javítottam. Még azt megkérdezném, hogy hogyan tárolja maga a gép azt, hogy most ez elõjeles, vagy nem. Azt értem, hogy az utolsó bit jelenti azt, de ha te most lefoglalsz egy elõjel nélkülit (unsiged int pl), akkor azt most a gép honnan fogja tudni, hogy ott az utolsó bit nem az elõjelet jelenti? Tárol erre még valahol valamit, hogy tudja, hogy nem az elõjel az utolsó bit, hanem azis \"bele tartozik\".? [/quote] A Pawn mint tudjuk, egy eléggé korlátozott nyelv. Engem is érdekelt ez a kérdés, ezért utána kerestem, és SA:MP wikin (ITT) meg is találtam a választ. A Pawn-ban nincs lehetõségünk unsigned int használatára. (csupán meg van említve, hogy létezik ilyen is). Ellenben a C-ben pl. elég sokféle változó létezik:
short int unsigned short int unsigned int int long int signed char unsigned char float double long double Azt most csak példának mutattam, mert az elv ugyanaz. Létezik egy úgynevezett szimbólumtábla, ami a következõ adatokat tárolja:
- szimbólum neve
- szimbólum attribútumai:
- definíció adatai
- típus
- tárgyprogram-beli cím
- definíció helye a forrásprogramban
- szimbólumra hivatkozások a forrásprogramban
Tehát innen tudja a program, hogy egy változó milyen típusú, így pl. az X-edik bit(jelen esetünkben pl. egy C int esetén, a 32. bit) MSB, vagy nem.
575
« Dátum: 2012. július 31. - 15:41:47 »
Igen, csak én abból indultam ki, hogy RGBA-t adunk meg, de végül is igazad van
576
« Dátum: 2012. július 31. - 11:03:12 »
Írtam ennél egyszerûbb változatot is:
stock RGBAToHex( r, g, b, a ) { return a | b << 8 | g << 16 | r << 24; }
Ez:
stock ShiftRGBAToHex(color) return (color >>> ;
Használata meg egyszerû:
printf(\"%x\", ShiftRGBAToHex(0xFFFFFFFF)); printf(\"%x\", ShiftRGBAToHex(0x8B0000FF)); //sötét piros
Az alábbit fogja kiprintelni nekünk:
FFFFFF 8B0000
Ez sem rossz, csak nem ugyanaz a kettõ Végül is a név az megtévesztõ. Az enyém az decimális RGBA értékekbõl konvertál egy Hex RGBA-t. Ez jól jöhet h pl. Paintban, PS-ben, vagy valami olyan programban, amely csak így írja ki a számokat(decimális alakban) h piros: 92, zöld: 72, kék:69, akkor azt tudod használni SA:MP-ban is. Amit te mutattál, az inkább RGBA > RGB konverter, mivel az alpha \"tartományt\" távolítja el. Illetve egy integer típúsú változó -2,147,483,648 és 2,147,483,647 közötti értéket vehet fel.[/quote] Igaz, elírtam, javítva.
Illetve a gumikat, ajtókat, világítást, illetve a panelt a SA-MP képes decimális számban is elmenti illetve beolvasni.[/quote] A SA:MP hál istennek korlátok nélkül képes dec-bin-hex-oct konvertálásokra, mivel amit mi decimális integernek látunk, valójában az is bináris szám, csak a mi kedvünkért konvertálja \"fel\" a program, a könnyebb kezelhetõség érdekében. Így változót kiírathatunk 4 féle képpen is:
printf(\"%b, %o, %d, %x\", integer, integer, integer, integer); Ergó 4 alakban is \"elmenthetjük\", de integerként a legegyszerûbb beolvastatni. (bár most így belegondolva, fogalmam sincs, h a strval képes-e a decimálison túl más értékeket is kezelni, de kétlem).
Szerintem ide még besorolhatnád a \"char\" típusú tömböket is, amely lecsökkenti ezen értékek számát 0 és 255 közé. Szóval a cellák méretét 1bájtnyira csökkenti, magyarán 8bites-be.[/quote] Hú, erre nem is gondoltam. Annyit foglal mint egy boolean, és 8 igaz/hamis értéket el lehet benne tárolni.
Igaz, nem olvastam el, mivel most keltem, viszont szép leírás. [/quote]
Szép leírás, csak az a baj hogy én még nem értek belõle semmit sem. [/quote] Köszönöm
577
« Dátum: 2012. július 30. - 23:06:51 »
Valóban, ez is egyfajta megoldás. Bár én úgy írnám, hogy a 0x81FFFFFF helyett ~(0x3F << 25), és akkor már jobban látható egy kevésbé hozzáértõ számára is, hogy mirõl is van szó Igazából a bitmûveletek \"szépsége\", hogy rengeteg lehetõséget nyitnak meg. Az ötletedet (azaz hogy ne a teljes változót kelljen felülírni néhány bit miatt) felhasználva kicsit változtattam az általam írt 2 függvényen, egyrészt hozzáadtam egy 3.-at, másrészt a SetData-t SetDatas-ra neveztem át, és most már a SetData-val konkrétan célirányosan írhatunk felül. (most hogy így belegondoltam, kompett függvénykönyvtárat lehetne írni bitmûveletes változókezelésre, csak nem tudom lenne-e értelme, és hogy a gyakorlatban mennyi haszna lenne, megérné-e egyeltalán a belefektetett idõt, hisz nem lenne könnyû, és kellene a mûködéséhez egy \"konfig\" rész is, akkor meg már nem hinném, hogy \"kezdõ\" is belekezdene, aki meg érti hogy mûködik, annak egyszerûbb lenne sajátot írni) Íme a módosított verzió: #define DATA_HOUSE 0 #define DATA_FACTION 1 #define DATA_RANK 2 #define DATA_PHONESTATE 3 #define DATA_DUTYCAR 4 #define DATA_JOB 5 stock GetData(playerinfo, data) { switch(data) { case DATA_HOUSE: return playerinfo & 127;//7 bit case DATA_FACTION: return playerinfo >> 7 & 15;//4 bit case DATA_RANK: return playerinfo >> 11 & 7;//3 bit case DATA_PHONESTATE: return playerinfo >> 14 & 1;//1 bit case DATA_DUTYCAR: return playerinfo >> 15 & 255;//8 bit case DATA_JOB: return playerinfo >> 23 & 15;//4 bit } return -1; } stock SetData(&playerinfo, data, value) { switch(data) { case DATA_HOUSE: { playerinfo = playerinfo & ~127 | value; }//7 bit (0-127 közötti maximálisan) case DATA_FACTION: { playerinfo = playerinfo & ~(15 << 7) | value << 7; }//4 bit (0-15 között) case DATA_RANK: { playerinfo = playerinfo & ~(7 << 11) | value << 11; }//3 bit (0-7 között) case DATA_PHONESTATE: { playerinfo = playerinfo & ~(1 << 14) | value << 14; }//1 bit (0-1) case DATA_DUTYCAR: { playerinfo = playerinfo & ~(255 << 15) | value << 15; }//8 bit (0-255 között) case DATA_JOB: { playerinfo = playerinfo & ~(15 << 23) | value << 23; }//4 bit (0-15 között) } return -1; } stock SetDatas(&playerinfo, house, faction, rank, phonestate, dutycar, job) { playerinfo |= house | (faction << 7) | (rank << 11) | (phonestate << 14) | (dutycar << 15) | (job << 23); } Fõpostban is frissítettem
578
« Dátum: 2012. július 30. - 17:47:32 »
Örülök ha hasznos volt Az a 0xFF-et tényleg elírtam, köszönöm, javítom is
579
« Dátum: 2012. július 30. - 13:23:10 »
Ezt a témát már jóval régebben meg akartam írni, mert tudom, hogy sokan hallottak a bitmûveletekrõl, de a nagy többség nem igazán tudja mire is jó, és hogyan kell használni. A téma elsõ felében a bitmûveleteket fogom taglalni, ez egy fõként elméleti rész lesz, míg a második felében gyakorlatban is megmutatom, mire is jó ez az egész, többek között elmagyarázom hogyan is mûködik az a bizonyos 4 függvény, mely egy jármû állapotát állíthatjuk be(encode_lights, encode_tires, encode_doors, encode_panels), és még pár apróbb érdekességet mutatok ezzel kapcsolatban. Elõször is el kell fogadni egy dolgot: ez nem kezdõknek való. A bitmûveletek nem alapszintû tudást igényelnek, és hál\' Istennek, elég ritkán van rájuk szükség. Azonban, a SA:MP-ban is tudjuk hasznosítani, többféleképpen is. Erre majd késõbb kitérek.
Tartalomjegyzék - 1. Bitmûveletek
1. Bitmûveletek 1.1 BevezetésA bitmûveletek arra használhatóak, hogy az egész számok bitjeit külön-külön kezelhessük. Mint írtam, erre egy átlag \"programozónak\" (a pawn scripter nagyon messze áll a programozótól...) elég ritkán van szüksége, de vannak helyzetek, mikor jól jöhet ha ismerjük. A bitmûveletek megértéséhez elõször is tisztában kell lennünk a kettes számrendszerrel. 1.2 A kettes (bináris) számrendszerA kettes vagy bináris számrendszerben az 1-es és a 0-s számjegyekkel ábrázoljuk a számokat. Digitális áramkörökben is a kettes számrendszerrel való számolást a legegyszerûbb megoldani, ezért szinte biztosak lehetünk benne, hogy manapság a számítógépekben, és szinte minden modern elektronikai eszközben ilyen számrendszert használnak programok. Arról nem igazán szeretnék írni, hogy hogyan is lehet számolni kettes számrendszerben, egyrészt mert erre nem lesz feltétlen szükségünk (persze nem árt ha megértjük), másrészt akit érdekel az úgyis utána fog nézni, rengeteg jó forrás, leírás található errõl a neten. 1.3 Részletesebben a bitekrõl a Pawn-banA bit az információ alapegysége a számítástechnikában. Kétféle értéke lehet: 0(hamis) és 1(igaz). A név az angol binari digi t, vagyis bináris számjegy kifejezésbõl származik. Manapság rengeteg programozási nyelv létezik, melyek eltérnek abban, hogy hány bites változókat használnak az adott nyelvben. A Pawn egy 32 bites programozási nyelv, vagyis minden változó 4 bájt(byte), vagyis 32 bit(bit). Ebbõl joggal következtethetünk arra, hogy a 2 32-1 a maximális legnagyobb eltárolható érték. Azért kell a -1, mert 0-tól indítjuk a számolást. Ez azt jelentené, hogy a maximális eltárolható érték 4,294,967,295. Ez azonban nem így van. Hogy miért is nem, ahhoz elõször is jöjjön egy kis háttérinfó. A legtöbb(minden) programozási nyelv esetén találkozhatunk integer változókkal. Ezeknek 2 típusát különböztetjük meg. Léteznek az úgynevezett elõjeles egész változók(signed integers), és léteznek elõjel nélküli(más néven pozitív) egész változók(unsigned integers). A különbség a kettõ között, hogy még egy elõjeles egész változóban eltárolhatsz negatív értéket is, addig az pozitív egész változóban nincsenek negatív számok. Utóbbinak tehát 4,294,967,295 a maximális eltárolható értéke. A Pawn azonban nem az utóbbi típust használja. A Pawn elõbbi, vagyis elõjeles egész változókat (signed integers) használ. 1 bitet fenntart a 32-bõl az elõjel számára(pozitív, vagy negatív). Ezt a bitet szokás MSB-nek(Most significant bit) hívni. Ha ez a bit be van kapcsolva, akkor a szám negatív, ha ki vna kapcsolva, akkor a szám pozitív. Így már egybõl érthetõ, hogy miért is 2 31-1 a maximális eltárolható érték, és nem pedig 2 32-1. Ebbõl következik tehát, hogy a Pawn-ban az integer változók értékkészlete: -2 31(-2,147,483,648) és 2 31-1(2,147,483,647) közötti számok. Ha egy változó létezik, akkor abban minden esetben, mind a 32 bit \"használtban\" van. A bináris számok elé bármennyi 0-t írhatunk, az értéke nem változik. Ez azt jelenti, hogy figyelembe kell vennünk, hogy ha nekünk az 1-es szám van eltárolva, mely alapból a bináris számrendszerben 1, az a Pawnban 00000000000000000000000000000001-ként lesz eltárolva. Ez késõbb még fontos lesz! A késõbbiekben szükségünk lesz még egy háttér információra. A Pawn egy úgynevezett 2-es komplementer rendszert használ, hogy elõállítsa a negatív számokat. Akik jártasak a C-ben, azon belül is a bitmûveletekben, azok tudják mit is jelent ez. Nem olyan bonyolult, tehát: fogjuk az alap számot, és minden bitet kicserélünk az ellentétére. Tehát az egyeseket 0-ra, a nullákat 1-esre. Végül a számhoz hozzáadunk egyet, és ezzel meg is kaptuk a negatív számot. Itt egy példa: 00000000000000000000000000000001 | // | 1
| 11111111111111111111111111111110 | // | minden bit komplementerét vesszük
| 11111111111111111111111111111111 | // | hozzáadtunk egyet, így megkaptuk a -1-et.
| [/quote]
1.4 Operátorok A bitekkel mûveleteket végezhetünk, ehhez különbözõ operátorok állnak rendelkezésünkre. Lentebb minden operátort egyesével ki fogok fejteni, azt is, hogy mit csinál, és leírom az igazságtáblázatukat is. Konkrétan a következõ operátorok állnak rendelkezésünkre:
- Bitenkénti (bitek közötti) ÉS
- Bitenkénti (bitek közötti) VAGY
- Bitenkénti (bitek közötti) KIZÁRÓ VAGY
- Bitenkénti (bitek közötti) NEGÁLÁS
- Biteltolás (arithmetic shift, shiftelés) operátor(ok)
- Logikai biteltolás (logical shift, logikai shiftelés) operátor
Az elsõ négy felsorolt operátor tartozik a logikai operátorok közé, még az utolsó elõtti(igazából utolsó elõtti kettõ, mert tolhatjuk jobbra, illetve balra, azaz 2 shiftelõ operátor lesz), és az utolsó biteltolási mûvelet. Az operátorok a számok azonos helyi értékû bitjei között mûködnek, a számok minden egyes bitjére.
1.4.1 Bitenkénti (bitek közötti) ÉS mûvelet A bitenkénti ÉS mûvelet (AND, &) egy logikai operátor. Fontos, hogy nem összekeverendõ az \"&&\" logikai operátorral! Hasonlít rá, de ez a mûveleteket bitenként végzi. Ez az operátor csak akkor ad eredményül 1-et, ha mindkét bit 1, minden más esetben az eredmény 0. Igazság táblázata:
[/quote] Példának nézzük meg, mi történik, ha a bitenkénti ÉS operátort alkalmazzuk, a 11 és a 7 esetén. A 11 bináris számrendszerben 00000000000000000000000000001011-nek felel meg, a 7 pedig 00000000000000000000000000000111-nek. Tehát a 11&7, az ugyaz mint ha ezt írnám: 00000000000000000000000000001011 & 00000000000000000000000000000111. Az átláthatóság kedvéért most egymás alá fogom írni a 2 számot, hogy áttekinthetõbb legyen, és az eredményt pedig a 3. sorba:
| 00000000000000000000000000001011 | & | 00000000000000000000000000000111 | | 00000000000000000000000000000011 | [/quote] Eredményül tehát 00000000000000000000000000000011-et kaptunk, ami a kettes számrendszerben a 3-asnak felel meg. A következõ 2 sor tehát ugyanazt jelenti:
Bin:
| 00000000000000000000000000001011
| & | 00000000000000000000000000000111
| = | 00000000000000000000000000000011
| Dec:
| 11
| & | 7
| = | 3
| [/quote] Még néhány példa, de ezeket már nem részletezem:
00000000000000000000000000000011 & 00000000000000000000000000000101 = 00000000000000000000000000000001 00000000000000000000000001110110 & 00000000000000000000000001011001 = 00000000000000000000000001010000 [/quote]
1.4.2 Bitenkénti (bitek közötti) VAGY mûvelet A bitenkénti VAGY mûvelet (OR, |) egy logikai operátor. Fontos, hogy nem összekeverendõ a \"||\" logikai operátorral! Hasonlít rá, de ez a mûveleteket bitenként végzi. Ez az operátor akkor ad eredményül 1-et, ha legalább az egyik bit 1. Ha egyik bit sem 1, akkor 0-t ad eredményül, ha mindkét bit 1, akkor is 1 az eredmény. Igazság táblázata:
[/quote] Példának nézzük meg, mi történik, ha a bitenkénti VAGY operátort alkalmazzuk, szintén a 11 és a 7 esetén. A 11 bináris számrendszerben mint már írtam 00000000000000000000000000001011-nek felel meg, a 7 pedig 00000000000000000000000000000111-nek. Tehát a 11 | 7, az ugyaz mint ha ezt írnám: 00000000000000000000000000001011 | 00000000000000000000000000000111. Az átláthatóság kedvéért ismét egymás alá fogom írni a 2 számot, hogy áttekinthetõbb legyen, és az eredményt pedig a 3. sorba:
| 00000000000000000000000000001011 | | | 00000000000000000000000000000111 | | 00000000000000000000000000001111 | [/quote] Eredményül tehát 00000000000000000000000000001111-et kaptunk, ami a kettes számrendszerben a 15-nekk felel meg. A következõ 2 sor tehát ugyanazt jelenti:
Bin:
| 00000000000000000000000000001011
| | | 00000000000000000000000000000111
| = | 00000000000000000000000000001111
| Dec:
| 11
| | | 7
| = | 15
| [/quote] Megint néhány példa:
00000000000000000000000000000011 | 00000000000000000000000000000101 = 00000000000000000000000000000111 00000000000000000000000001110110 | 00000000000000000000000001011001 = 00000000000000000000000001111111 [/quote]
1.4.3 Bitenkénti (bitek közötti) KIZÁRÓ VAGY mûvelet A bitenkénti KIZÁRÓ VAGY mûvelet (XOR, ^) egy logikai operátor. Ez az operátor nagyon hasonlít a VAGY operátorra, az a fõ különbség a kettõ között, hogy amennyiben mindkét bit 1-es, akkor a KIZÁRÓ VAGY operátor 0-t ad eredményül, a többi esetben ugyanúgy viselkedik mint a VAGY operátor. Igazság táblázata:
[/quote] Példának nézzük meg, mi történik, ha a bitenkénti KIZÁRÓ VAGY operátort alkalmazzuk, szintén a 11 és a 7 esetén. A 11 bináris számrendszerben mint már írtam 00000000000000000000000000001011-nek felel meg, a 7 pedig 00000000000000000000000000000111-nek. Tehát a 11 ^ 7, az ugyaz mint ha ezt írnám: 00000000000000000000000000001011 ^ 00000000000000000000000000000111. Az átláthatóság kedvéért ismét egymás alá fogom írni a 2 számot, hogy áttekinthetõbb legyen, és az eredményt pedig a 3. sorba:
| 00000000000000000000000000001011 | ^ | 00000000000000000000000000000111 | | 00000000000000000000000000001100 | [/quote] Eredményül most 00000000000000000000000000001100-t kaptunk, ami a kettes számrendszerben a 12-nek felel meg. Érdekes, hogy teljesen más eredményt kapunk, pedig lényegében ugyanazt az eredményt adja az operátor, - kis különbséggel ugyebár - mint a VAGY operátor.A következõ 2 sor tehát ugyanazt jelenti:
Bin:
| 00000000000000000000000000001011
| ^ | 00000000000000000000000000000111
| = | 00000000000000000000000000001100
| Dec:
| 11
| ^ | 7
| = | 12
| [/quote] Megint néhány példa:
00000000000000000000000000000011 ^ 00000000000000000000000000000101 = 00000000000000000000000000000110 00000000000000000000000001110110 ^ 00000000000000000000000001011001 = 00000000000000000000000000101111 [/quote] Ezzel kapcsolatban egy érdekességet mutatnék meg. Vegyünk 2 számot. A látványosság kedvéért én példának a 118-at és a 89-et veszem.
1. szám: 00000000000000000000000001110110 = 118 2. szám: 00000000000000000000000001011001 = 89 Mûvelet elvégzése: 00000000000000000000000001110110 ^ 00000000000000000000000001011001 = 00000000000000000000000000101111 = 47 1. szám az eredmény, 2. szám az eredeti 2. szám: 00000000000000000000000001011001 = 89 Eredmény: 00000000000000000000000000101111 ^ 00000000000000000000000001011001 = 00000000000000000000000001110110 = 118 [/quote] Vagyis visszakaptuk a kiindulási állapotot
1.4.4 Bitenkénti (bitek közötti) NEGÁLÁS A bitenkénti NEGÁLÁS (NOT, ~) az utolsó logikai operátor, melyet meg fogok mutatni. Ez az operátor eléggé eltér az eddigiektõl, leginkább abban, hogy ezt a mûveletet nem 2 bitre alkalmazzuk, hanem csak 1-re. Szokás komplementer-operátornak is hívni(konyhanyelven). Lényegében az 1-esekbõl 0-t, a 0-kból 1-est csinál. Igazság táblázata:
[/quote] Példának nézzük meg, mi történik, ha a bitenkénti NEGÁLÁST alkalmazzuk a 7-es számra. A 7 bináris számrendszerben mint már írtam 00000000000000000000000000000111-nek felel meg. Tehát a ~7, az ugyaz mint ha ezt írnám: ~00000000000000000000000000000111. Nézzük tehát, mi történik:
~ | 00000000000000000000000000000111 | | 11111111111111111111111111111000 | [/quote] Eredményül most 11111111111111111111111111111000-t kaptunk, ami a kettes számrendszerben a -8-nak felel meg. A következõ 2 sor tehát ugyanazt jelenti:
Bin:
| ~ | 00000000000000000000000000000111
| = | 11111111111111111111111111111000
| Dec:
| ~ | 7
| = | -8
| [/quote] Megint néhány példa:
~00000000000000000000000000000101 = 11111111111111111111111111111011 ~00000000000000000000000001110110= 11111111111111111111111110001010 [/quote] Ehhez kapcsolódóan lenne itt egy fontos megjegyzendõ dolog. Aki nem érti, hogy miért -8 a megoldás, az nem olvasta el elég rendesen a \"Részletesebben a bitekrõl a Pawn-ban\" részt.
1.4.5 Biteltolás (arithmetic shift, shiftelés) operátor(ok) A shift operátorok(<<, >>) a bitek tologatására használhatóak. A << balra tol, a >> jobbra. Bal oldalt található a szám, amit tologatni kívánunk, jobb oldalt pedig az, hogy mennyivel szeretnénk eltolni. 1.4.5.1 Jobbra toló operátor(>>): Ez az operátor a szám bitjeit jobbra tolja a megadott mértékkel. Egy bittel való eltolás, 2-vel való osztásnak felel meg. Nézzünk egy példát:
| 00000000000000000000000000001000 | //8 | >> | 2 | | 00000000000000000000000000000010 | //2 | [/quote] Láthatjuk, hogy semmi más nem történt, mint minden bitet 2-vel hátrébb mozgattunk. Az így \"megüresedett\" bitek helyére pedig 0-k kerültek. Lényegében az történt, hogy az utolsó 2 bit kiesett, az így megmaradt biteket 2-vel hátrébb csúsztattuk, majd az elsõ 2, így \"üres\" bit 0 értéket kapott. Nézzünk egy példát negatív számmal:
| 11111111111111111111111111110000 | //-8 | >> | 2 | | 11111111111111111111111111111100 | //-2 | [/quote] Láthatjuk, hogy itt fontos szerepe van az MSB-nek. Ettõl függ ugyanis, hogy 0-k vagy 1-esek kerülnek a \"megüresedett\" bitek helyére. Fontos tehát megjegyezni, hogy a jobbra shiftelés megtartja a számok elõjelét, nem változtat azon! 1.4.5.2 Balra toló operátor(<<): Ez az operátor a szám bitjeit balra tolja a megadott mértékkel. Egy bittel való eltolás, 2-vel való szorzásnak felel meg. Nézzünk egy példát:
| 00000000000000000000000000001000 | //8 | << | 2 | | 00000000000000000000000000100000 | //32 | [/quote] Itt megint könnyedén észrevehetõ mi is történt. Minden bitet fentebb \"toltunk\" 2-vel. Azok a bitek, amelyek ezáltal a 32. bit elé kerültek, kiesnek. Az így megüresedett bitek 0-kkal egészültek ki. Eddig nem túl bonyolult. Azonban figyeljünk oda, ha túl sokáig shiftelünk egy pozitív számot, akkor az utolsó érték, melyet fel tud venni a változónk (mielõtt még túlcsordulás miatt elérné a 0-t), az egy negatív szám! Nézzük mi történik negatív számok esetén:
| 11111111111111111111111111111000 | //-8 | << | 2 | | 11111111111111111111111111100000 | //-32 | [/quote] Láthatjuk hogy a balra shifteléskor a szám mindig 0-kkal egészítõdik ki, legyen az akár negatív, akár pozitív. Nem veszi figyelembe az MSB értékét, így ha túl sokat shiftelünk, akkor elõfordulhat, hogy a szám elveszti negatív értékét, és eléri a 0-t.
1.4.6 Logikai biteltolás (logical shift, logikai shiftelés) operátor Elõször is le kell tisztázni, hogy logikai shiftelésbõl csak egy létezik, jobbra logikai shiftelés(>>>). Sokban hasonlít a jobbra shiftelõ operátorra (>>), azonban van egy fontos különbség. Nézzük az elsõ példát:
| 00000000000000000000000000001000 | //8 | >>> | 2 | | 00000000000000000000000000000010 | //2 | [/quote] Eddig nem igazán tapasztalhattunk semmi változást, minden pont ugyanúgy zajlott, mint a jobbra shiftelésnél(>>). Nézzük mi történik negatív szám esetén:
| 11111111111111111111111111111000 | //-8 | >>> | 2 | | 00111111111111111111111111111110 | //1073741822 | [/quote] Itt már láthatjuk a különbséget. Logikai shiftelés esetén az üres bitek helyére bekerülõ érték nem függ az MSB-tõl, hanem mindig 0. Emiatt soha nem kaphatunk eredményül negatív számot, logikai shiftelés esetén.
1.5 Elsõ fejezet vége Nos, ezennel átvettünk mindent, amit érdemes tudni a bitmûveletekrõl. Megmutattam az alapok, hogy hogyan épülnek fel a változók, valamint átvettük a fõ operátorokat. Eddig csak színtiszta elmélet volt. A következõ részben megmutatom, hogyan hasznosíthatjuk mindezt a gyakorlatban, vagyis mire is jó az a sok marhaság, amit eddig leírtam.
2. Gyakorlati példák, érdekességek 2.1 Áttekintés, mikrõl is lesz még szóAz alábbiakban még pár dolgot szeretnék mutatni. Elõször is néhány \"függvénnyel\" fogok foglalkozni, majd mutatok még egy-két érdekességet. Konkrétan megmutatom, hogyan tudjuk egy jármû minden \"paneljének\" adatát kiíratni, részletesen(erre alapból nincs lehetõség, és a függvények is mind \"encode\" függvények, én viszont mutatok egy-egy decode \"verziót\" is.) Az alábbi 4 függvénnyel fogok foglalkozni: - encode_tires
- encode_panels
- encode_doors
- encode_lights
De elõbb egy kis háttérinfó: A Pawnban a forrásban megadhatunk bináris számokat ugyanúgy, ahogyan Hex számokat is megadhatunk. Ehhez a \"0b\" prefixet kell használnunk. Tehát ha bináris számunk az 1011 és ezt akarjuk adni értékül egy változónak, azt így tehetjük meg: new var = 0b1011; 2.2 encode_tiresHáttér információ: A SA:MP-ban egy jármû abroncsainak adataid 4 bit tárolja. Az elsõ bit a jobb hátsó, a második bit a jobb elsõ, a harmadik bit a bal hátsó, a negyedik bit pedig a bal elsõ abroncsról tárol információt. Mivel 4 bitben eltárolhatóak az információk, így decimális formában 0-15 értékekkel is be lehet állítani a jármûvek abroncsait. 16-tól kezdve az értékek már ismétlõdni kezdenek, szóval a 16-nál az eredmény ugyanaz mint 0-nál, 17-nél ugyanaz mind 1-nél, és így tovább. Ez érthetõ, ha tudjuk hogyan épül fel a kettes számrendszer.(Ne felejtsük el, a biteket hátulról számozzuk!) Nos nézzük hogyan néz ki a kód: encode_tires(tire1, tire2, tire3, tire4) { return tire1 | tire2 << 1 | tire3 << 2 | tire4 << 3; } Láthatjuk, hogy bekérjük a 4 abroncs adatát(vagyis hogy ép[0], vagy kidurrant[1]), majd egy sima bitenkénti VAGY mûvelet és biteltolás kombinálásával visszatérünk az eredménnyel. A kódban a tire1 felel meg a jobb hátsó abroncsnak, a tire2 a jobb elsõ, a tire3 a bal hátsó, és a tire4 a bal elsõnek. Nézzünk egy konkrét példát. Tegyük fel, hogy én a hátsó 2 abroncsot ki akarom durrantani, még az elsõ kettõt épre akarom beállítani. Ez esetben így néz ki a dolog: encode_tire(1,0,1,0); Ha kiíratnánk konzolba a visszatérési értéket (%d-vel), 5-öt kapnánk. Miért is? Az 5 bináris alakja 0101. Hoppá, ha megnézzük ez pont fordítottja annak, amit mi megadtunk számjegyekként, csak már konkrét bináris számként. Nézzük hogyan is történhetett mindez, mit is csináltunk. A függvény a következõ mûveletet végzi: tire1 | tire2 << 1 | tire3 << 2 | tire4 << 3 Konyhanyelven úgy magyarázhatnánk el a dolgot, hogy ez a kód egymás mellé pakolgatja a megadott számokat, fordított sorrendben. Na de mi most nem a konyhanyelv miatt vagyunk ebben a leírásban, szóval nézzük a kódunkat. Lényegében ez futott le, a konkrét értékeinkkel nézve: 1 | 0 << 1 | 1 << 2 | 0 << 3 Bármily furcsa is, ez egy mûvelet, melyen szépen végig halad sorban a program. Elõször is írjuk át az egészet bináris alakba(az egyszerûség kedvéért most csak 4 bitet fogok kiírni): 0001 | 0000 << 1 | 0001 << 2 | 0000 << 3 Na erre se mondtuk volna rá a tutorial elsõ részének elolvasása elõtt, hogy ez egy mûveletsor. A rendszer elsõnek az eltolásokat végzi el (olyan ez mint a 2*3+2*4+2*5 mûveletben elõször a szorzásokat végezzük el, és csak utána adunk össze, ha nincs zárójel), és csak utána a bitenkénti VAGY mûveleteket, ezért mi is így fogunk tenni. Emlékezzünk, eltoláskor az \"üres\" bitek 0 értéket fognak felvenni. Végezzük el külön csak az eltolásokat: 0000 << 1 = 0000 0001 << 2 = 0100 0000 << 3 0000 Nos, ha ezeket elvégeztük, akkor nézzük, hogy is áll most a kódunk: 0001 | 0000 | 0100 | 0000 Négy azonos mûvelet van hátra, így hát a program innen más szépen sorban fog haladni. Tegyünk mi is így. Elsõ tehát a 0001 | 0000 mûvelet elvégzése. Emlékeztetõül, a bitenkénti VAGY mûvelet akkor ad 0-t eredményül, ha mind a kettõ érték 0, minden más esetben 1-et. Végezzük el külön az elsõ bitenkénti VAGY mûveletet: 0001 | 0000 = 0001 Nem volt bonyolult, nézzük tehát hogy áll akkor most a teljes mûveletünk: 0001 | 0100 | 0000 Haladunk szépen tovább, elvégezzük a 0001 | 0100 mûveletet. 0001 | 0100 = 0101 Nincs mit magyarázni rajta, egyszerû bitenkénti VAGY mûvelet volt ez is. Már csak ez van hátra: 0101 | 0000 Nos, ez sem lesz egy bonyolult mûvelet: 0101 | 0000 = 0101 Ezzel meg is kaptuk a végeredményt, ami nem más, mint a 0101 (tízes számrendszerben 5). Mivel azonban eléggé kusza lett így a számításunk, nézzük egyben hogyan is néz ki az egész, ha nem bontom ennyire részekre: 0100 | 0000 << 1 | 0001 << 2 | 0000 << 3 v 0001 | 0000 | 0100 | 0000 v 0001 | 0100 | 0000 v 0101 | 0000 v 0101 Nos, ezennel láthattuk a gyakorlatban is, hogyan mûködik a függvény. Kijelenthetjük tehát, hogy a függvény a számokat a sorrendjüknek megfelelõ számú bitbe helyezi. Mivel azonban a biteket hátulról számozzuk, így az 1,0,1,0 bemenetek végeredménye 0101 lesz. Így már nem is olyan bonyolult Na, ha már ilyen sokáig eljutottunk, akkor felhasználhatjuk ezt a kódot arra, hogy az alapjait figyelembe véve elkészítsük a decode változatot. Mivel 4 értékkel térünk vissza, ezért paraméterként kell majd 4 változó, melyeknek módosíthatjuk az értékét, illetve 1 paraméter pedig a dekódolandó szám. A függvényünk \"címsora\" tehát így néz ki: decode_tires(tires, &tire1, &tire2, &tire3, &tire4) Hogy példánk ne csak elmélet legyen, a tires változó legyen az elõbbi 0101 értékkel egyenlõ. Na akkor menjünk tovább. Bemeneti értékünk ugye a \"tires\" változóban lesz eltárolva, így ezzel fogjuk a mûveleteket végezni. Kezdjünk el gondolkozni. Hogyan is tudnánk ellenõrizni egy adatot. Legegyszerûbb ha a bitenkénti ÉS mûveletet alkalmazzuk. Miért is? Nos, a bitenkénti ÉS mûvelet ugye akkor ad eredményül 1-et, ha mind a 2 érték egy. Tehát ha min egy számot összehasonlítunk a 1-el(binárisan ugye 00000000000000000000000000000001, akkor az eredményünk lényegében arról fog tájékoztatni, hogy az elsõ bit 0, vagy 1. Nem is olyan bonyolult ez. Nézzük akkor az elsõ bitet. Arra emlékezhetünk még, hogy az elsõ bit a tire1, vagyis jobb hátsó abroncs adatait tárolja. Tehát: tire1 = tires & 1; Vagy konkrétan a példánk esetében: tire1 = 0101 & 0001 Mivel a bitenkénti ÉS mûvelet akkor ad 1-et eredményül, ha mind a kettõ bit 1, akkor már láthatjuk is, hogy miért elegendõ az elsõ bitet szemügyre venni. Mivel mind a 2 helyen az elsõ bit 1, ezért a tire1 változónk értéke is 1(0001) lesz. Egyszerû és nagyszerû, máris megkaptuk a jobb hátsó abroncs állapotát. Gondolkozzunk hát tovább. Nekünk most arra van szükségünk, hogy a 2. bit értékét megkapjuk. Hogyan kaphatjuk ezt meg? Legegyszerûbb megoldás, ha a tires változót jobbra shifteljük 1-el, majd ismételten bitenkénti ÉS mûveletet végzünk. Nézzük tehát, hogyan is nézne ez ki: tire2= tires >> 1 & 1; Vagy konkrétan a mi példánkban: tire2 = 0101 >> 1 & 0001 v tire2 = 0010 & 0001 Ismételten bitenkénti ÉS mûvelet, és az eredményünk 0, mivel csak az egyik bit 1, a másik 0, így a bitenkénti ÉS mûvelet eredménye is 0. Ezen az elven megcsináljuk a maradék 2 abronccsal is: tire3= tires >> 2 & 1; tire4= tires >> 3 & 1; Vagy a mi esetünkben konkrét példánkkal: tire3 = 0101 >> 2 & 0001 // azaz: --> 0001 & 0001 = 1 tire4 = 0101 >> 3 & 0001 // azaz: --> 0000 & 0001 = 0 A teljes kódunk tehát: decode_tires(tires, &tire1, &tire2, &tire3, &tire4) { tire1 = tires & 1; tire2 = tires >> 1 & 1; tire3 = tires >> 2 & 1; tire4 = tires >> 3 & 1; } A konkrét példánkban a 4 változónk értéke a függvény lefutása után: tire1: 1 tire2: 0 tire3: 1 tire4: 0 Ha összehasonlítjuk, ezek pont azok az értékek, mint amiket az encode függvényben megadtunk, tehát úgy tûnik jól dolgoztunk 2.3 encode_lightsEz a rész lesz a legrövidebb. Az egész lámpás rész pontosan ugyanarra a sémára épül mint az abroncsok. Az adott bitek ugyanazon a \"helyen\" lévõ lámpa adatait szolgáltatják, ugyanúgy 0 az ép, és 1 a sérült lámpák állapot azonosítója, és ugyanúgy 1-1 bit tárolja az értékeket. Maga a kód: encode_lights(light1, light2, light3, light4) { return light1 | light2 << 1 | light3 << 2 | light4 << 3; } Láthatjuk hogy halál pontosan ugyanaz mint az encode_tires, csak más változónevekkel. Így hát a decode függvény is ugyan az lesz, csak a változóneveket kell módosítanunk: decode_lights(lights, &light1, &light2, &light3, &light4) { light1 = lights & 1; light2 = lights >> 1 & 1; light3 = lights >> 2 & 1; light4 = lights >> 3 & 1; } Ha megnézzük látjuk, hogy teljesen ugyan az a séma, ugyan az a felépítés, minden megegyezik, ezért nem is írtam le újból ugyanazt, amit egyszer már kifejtettem. 2.4 encode_panelsHáttér információ: A SA:MP 7 panelrõl tárol adatokat. Egy panel adatait 4 bit írja le. Nos, ennél több infóra nekünk most nincs szükségünk, az elõzõ kód alapján ezen kód is megérthetõ, így az encode verzióhoz nem is nagyon szeretnék magyarázatot fûzni. A különbség az encode_tires-hez képest, hogy itt 4-essével shiftelünk, mivel 1 panel adatait 4 bit tárolja. Maga a kód: encode_panels(flp, frp, rlp, rrp, windshield, front_bumper, rear_bumper) { return flp | frp << 4 | rlp << 8 | rrp << 12 | windshield << 16 | front_bumper << 20 | rear_bumper << 24; } Nézzünk egy decode verziót, ehhez a kódhoz. Alapjaiban ugyanazon a vonalon kell elindulnunk, mint a decode_tires esetében. Itt most 7 visszatérési értékünk lesz, és 1 bemeneti érték. Tehát így néz ki a függvény header: decode_panels(panels, &flp, &frp, &rlp, &rrp, &windshield, &front_bumper, &rear_bumper) A folytatásban megint csak az elõbbi verziót kell alapul vennünk, azonban itt lesz egy kis különbség. Egyértelmû, hogy mivel 1 panel adatait 4 bit tárolja, így a 4 bitet nekünk egyben kell lekérni, és egyben kell vele visszatérnünk. Megint csak a bitenkénti ÉS mûveletet fogjuk alkalmazni, azonban mivel 4 bitrõl van szó, így egy olyan számmal kell összehasonlítanunk, mely bináris alakban 1111. Ez a szám nem más, mint a 15. Hogy miért ez kell? Ha egy bitsorozat tartalmát ki szeretnénk másolni egy másik változóba, akkor a bitenkénti ÉS mûveletre vna szükségünk. A bitenkénti ÉS mûvelet akkor ad 1-et eredményül, ha mindkét bit 1, ha valamelyik 0, akkor a visszatérés már 0 lesz. Ergó tehát, ha egy csupa 1-esekbõl álló bitsorozattal vetjük össze az eredeti bitsorozatunkat, akkor lényegében lemásoljuk a sorozatot, egy másik változóba, hisz eredményül mindig az eredeti sozatot fogjuk visszakapni. Íme néhány példa: 0101 & 1111 = 0101 1111 & 1111 = 1111 0000 & 1111 = 0000 1011 & 1111 = 1011 Láthatjuk tehát, hogy ha csupa 1-est tartalmazó bitsorozattal hasonlítjuk össze az eredeti számunkat, akkor lényegében egy másolatot készítünk. Mivel nekünk erre a 4 bitre van szükségünk a 32-bõl, így pontosan ezt kell tennünk, ezen 4 bitet lemásolni egy másik változóba, hogy késõbb ezt majd egy másik függvénnyel még jobban darabokra szedhessük. Íme tehát akkor a kódunk elsõ sora: flp = panels & 15; Mivel 4-esével vizsgáljuk a biteket, így lényegében annyit kell még változtatnunk az elõzõ kódon(decode_tires), hogy az 1-esével növekvõ shiftelések helyett 4-esével shifteljünk. Azaz a 2. panel adatainak lekérdezése: frp = panels >> 4 & 15; Innen pedig már csak mindig további 4 shiftelést el kell végeznünk, és szépen végig haladhatunk a panels változó bitjein, és megkaphatjuk minden panel adatait külön-külön. rlp = panels >> 8 & 15; rrp = panels >> 12 & 15; windshield = panels >> 16 & 15; front_bumper= panels >> 20 & 15; rear_bumper = panels >> 24 & 15; Ezennel minden panel adatait megkaptuk. Ezután már akár a decode_tires függvényt felhasználva szét lehet szedni az adatokat darabokra, de akár egy saját névvel, és más változó nevekkel ellátott másik függvényt is létre lehet hozni a decode_tires mintájára. Tehát az egész kód egyben: decode_panels(panels, &flp, &frp, &rlp, &rrp, &windshield, &front_bumper, &rear_bumper) { flp = panels & 15; frp = panels >> 4 & 15; rlp = panels >> 8 & 15; rrp = panels >> 12 & 15; windshield = panels >> 16 & 15; front_bumper= panels >> 20 & 15; rear_bumper = panels >> 24 & 15; } Igazából a függvény ugyanarra a sémára épül mint a decode_tires, csak annyi a különbség, hogy 4 bitenként kapjuk az adatokat, nem pedig egyesével, mivel itt minden panelnek 4 adatát tudjuk majd még lekérdezni. Nem tudom lehet-e még ehhez a részhez hozzáfûzni valamit, szóval szerintem ugorjunk. 2.5 encode_doorsHáttér információ: A SA:MP képes minden jármû 4 \"ajtajának\" állapotát tárolni. Ezek az \"ajtók\"(Doors-t hogy fordíthatnám jobban?) konkrétan a motorháztetõ, csomagtartó, vezetõoldali ajtó, és anyósülés oldali ajtó. A 2 hátsó ajtó állapotát jelenleg még nincs lehetõségünk lekérdezni. Amikor lekérdezzük egy jármû \"ajtajának\" adatait, azt a SA:MP 4 bájtként(32 bit) adja vissza. Ebbõl a 4 bájtból 1 bájt(8 bit) jut minden egyes objektumra. Vagyis minden egyes objektum adatait 8 bit tárolja. Vagyis tárolhatná... A SA:MP csak az elsõ 3 bitet használja, a további bitek üresek lesznek, nincs funkciójuk, talán majd késõbb lesz. Az elsõ bit azt tárolja, hogy az objektum zárt[0], vagy nyitott[1](nem az jelenti, hogy bezárt, hanem becsukott/kinyitott) állapotban van-e. A második bit azt adja meg, hogy az objektum ép[0] vagy sérült[1]. A 3. bit arról tájékoztat, hogy az adott objektum rajta van-e még a jármûvön[0] vagy már leesett[1]. A többi bit mint mondtam üres. Ez majd a decode függvénynél lesz fontos. Nézzük tehát a konkrét kódot: encode_doors(bonnet, boot, driver_door, passenger_door, behind_driver_door, behind_passenger_door) { #pragma unused behind_driver_door #pragma unused behind_passenger_door return bonnet | boot << 8 | driver_door << 16 | passenger_door << 24; } A 2 hátsó ajtóval nem foglalkozunk, mivel azok jelenleg még nem támogatottak ugyebár, de a kód készítõje gondolt a jövõre is, vagy fogalmam sincs miért adta meg ezt a két paramétert is, hisz ígyis-úgyis módosítani kell a kódon... Ha behoznak még 2 ajtót, akkor az 1 bájtos tárolással már 6 bájt lenne, de 1 változó maximum 4 bájt lehet, tehát a kódot úgyis módosítani kell, ha meg arra gondoltak, hogy legalább a paramétereket nem kell majd szegény scriptereknek minden sorban átírni, az megint hülyeség, hisz ki adna értéket olyan paraméternek, amely nincs használva?... Nos mindegy, nem a kritizálásért vagyunk most itt. Ha megnézzük, a kód 8-as shiftelést használ, mivel egy objektum adatait 8 bit tárolja. A mûködési elv ugyanaz, mint az elõzõ encode függvényeknél, így erre nem kívánok megint kitérni. Nézzük azonban hogyan írnánk ehhez egy decode függvényt. Mikor megkérdeztem errõl ismerõsömet, õ azt mondta, ugyanúgy mint az elõzõ, decode_panels függvénynél, csak 8-as shiftelést használunk, és 15 helyett 255-el végezzük a bitenkénti ÉS mûveletet. 255-el? minek? No erre is ki fogok térni késõbb, de haladjunk a szokásos módon. 1 bemeneti paraméterünk van, és 4 kimeneti, vagyis a header rész a következõ: decode_doors(doors, &bonnet, &boot, &driver_door, &passenger_door) Ezzel meg is vagyunk, itt nem látok különösebb magyarázni valót. Én most nem fogok törõdni a 2 nem létezõ ajtóval, ha egy jövõbeni verzióban netán azokat is behoznák mint lekérdezhetõ objektum, akkor ígyis-úgyis módosítani kell majd a kódot, addig meg úgysincs rá szükségünk. Nos, mint az eddigi decode függvényeknél, elsõ feladatunk egy shiftelés mentes bitenkénti ÉS mûvelet elvégzése. Az egyik megoldás a következõ: bonnet = doors & 255; Lehet így is. Azonban véleményem szerint felesleges itt egy ekkora számmal \"szenvednünk\". Miért használjunk ekkora számot, és ezáltal bonyolítsuk feleslegesen a kódunkat, ha nekünk a 8 bitbõl csak az elsõ 3 lesz ami adatot tárol? Bõven elegendõ egy olyan szám, amely bináris alakja 111. Ez nem más, mint a 7. Tehát a következõ megoldás ugyanúgy helyes: bonnet = doors & 7; A két kód pontosan ugyanazt az eredményt fogja visszaadni, semmi különbség a kettõ között. Csupán elsõ esetében nagy számmal dolgozunk, még második verzió esetén csak akkorával, amekkora szükséges. A kód többi részében csak 8-as shifteléssel végigcammogunk a doors változó többi bitjén is: boot = doors >> 8 & 7; driver_door = doors >> 16 & 7; passenger_door = doors >> 24 & 7; A teljes kód egyben: decode_doors(doors, &bonnet, &boot, &driver_door, &passenger_door) { bonnet = doors & 7; boot = doors >> 8 & 7; driver_door = doors >> 16 & 7; passenger_door = doors >> 24 & 7; } A kód pont ugyanazon az elven épül fel, mint az összes többi decode függvényünk, csak épp a benne használatos értékek az \"ajtó\" objectumok adatstruktúrájához vannak igazítva. 2.6 Egyéb ötletek gyakorlati alkalmazásra, hasznosításraJoggal felmerülhet a kérdés, hogy ennyi? Emiatt rágtuk végig magunkat ezen néhány tízezer karakteren? Nem. Nem ennyi. A SA:MP-ban rengeteg felhasználási módja lehet még a bitmûveleteknek. Mutatok is néhány dolgot, mire jók még. 2.6.1 RGBA->HEX; HEX->RGBA konvertálások Nos, bármily \"hihetetlen\", erre is használható. Miért is? Nos, 16-os számrendszerben 0-9, valamint A-F \"szánjegyek\" léteznek. A hexadecimális számjegy decimális értékben 0-15 lehet. Ha megnézzük bináris értékeket, 0-15 az 4 bittel leírható, hiszen a 15 az bináris alakban 1111. De ha józan paraszti ésszel belegondolunk is. 16 az 24. Így tehát 1 hexadecimális érték, az 4 bináris értékkel írható le. Ebbõl már sejthetõ, hogy itt is shiftelésre lesz szükségünk. Naná Mivel 4 bit ír le egy hexadecimális számjegyet, így 4-esével kell majd shiftelnünk. Mi is az az RGBA? RGBA: A színek olyan meghatározási módja, melyben a 3 alapszín([r]ed, [g]reen, lue) mellett egy 4. érték, az úgynevezett [a]lpha is szerepel, amely az áttetszõséget adja meg. A legtöbb program(pl. paint, PS), és pl. a css(külön függvénnyel!) is elfogadja ezen értékeket decimális számokként(0-255) is, a SA:MP-ban azonban hexadecimális alakban kell megadnunk. Bármily furcsa a következõ 4 sor pont ugyan azt jelenti:
\"Normál\" RGB alak(pl. paint, photoshop): Piros: 0, Zöld: 255, Kék: 255 CSS alak(függvénnyel): rgba(0, 255, 255, 1); Pawn alak(1): 0x00FFFFFF Pawn alak(2): 16777215
Ó igen, a Pawn-ban decimális számokként is megadhatjuk a színeket, hisz a program mindent bináris számrendszerbe fog átszámolni. De akár bináris alakban is megadhattuk volna:
Pawn alak(3): 0b111111111111111111111111
Az, hogy mi a Pawn-nak hexadecimális alakban szoktuk megadni, annak az egyetlen oka, hogy így a leginkább \"átlátható\", és ez egy amúgy is elfogadott módja (mármint a hexadecimális számmal való megadás) a színek leírásának a számítástechnikában.
Nos, mivel 1 szín 0 és 255 közötti értéket tartalmaz a piros, zöld és kék színekbõl, ez hexadecimálisan 2 számjeggyel leírható: 00-FF. Az FF értéke 255, aki nem hiszi, számoljon utána (162-1)
2 hexadecimális számjegy az pedig 8 bináris számjeggyel leírható(00000000-11111111). Így már láthatjuk, hogy 8-as shiftelésre lesz szükségünk. Másra nincs is szükségünk, az RGBA->HEX konverter elkészítéséhez.
stock RGBAToHex( r, g, b, a ) { return a | b << 8 | g << 16 | r << 24; }
Az, hogy miért fordított sorrendben kellett megadnunk az értékeket, az megint csak azzal magyarázható, hogy a biteket hétköznapi értelemben véve visszafelé számozzuk.
Egy ellentét, azaz HexToRGBA függvény megírása sem túl bonyolult, ugyan ezt kell csinálnunk, csak visszafelé.
stock HexToRGBA( colour, &r, &g, &b, &a ) { a = colour & 0xFF; b = (colour >> 8 ) & 0xFF; g = (colour >> 16 ) & 0xFF; r = (colour >> 24 ) & 0xFF; }
A 0xFF-et természetesen decimális értékkel is megadhatjuk(255).
No akkor lehet ugye RGBA-t ARGB-be is konvertálni, az így néz ki:
RGBAToARGBHEX(r,g,b,a) { return (r & 0xff) << 24 | (g & 0xff) << 16 | (b & 0xff) << 8 | a & 0xff; }
Ez máris egy újabb felhasználási módja a bitmûveleteknek. De, mutatok még
2.6.2 Boolen változók helyett Integer
Az al-al-alcímet elolvasva joggal felmerülhet a kérdés, hogy ez meg hogy jön ide. Nos ez úgy jön ide, hogy most egy kis memóriatakarékosságról fogok itt regélni. Adhattam volna azt is címnek, hogy miért ne használjunk boolean változókat, ha legalább 5 igaz/hamis értéket el akarunk tárolni.
Nos akkor egy kis memórialecke. Azt már tisztáztuk, hogy az integer változók 32 bitesek, vagyis 4 bájtot foglalnak le a memóriában maguknak. A boolean típusú változókról azonban még nem volt szó. Mivel 1 értéket tárolnak csak, az is csak igaz vagy hamis lehet, így joggal gondolhatnánk, hogy 1 bit a mérete. Azonban nem...
1 boolean változó 8 bitet, azaz 1 bájtot foglal le magának a memóriában. Hogy ez miért így van, az a számítógépek memóriahasználatával magyarázható. Manapság nincs mód arra, hogy a memóriában egyetlen bitet módosítsunk, csak 8-as \"csomagokban\", vagyis bájtonként tudjuk ezt megtenni. Hogy ez miért van így, azt most nem fogom itt fejtegetni
Nos, ha megnézzük tehát, a boolean változó egy nagyon-nagyon pazarló megoldás. Hiszen 1 darab boolean változó 1 bájtot foglal, 4 darab boolean változó esetén ez már 4 bájt, ami megegyezik 1 integer változó méretével. Azonban, még a 4 boolean változóban 4 igaz/hamis érték kerülhet tárolásra, addig egy integerben 32 igaz/hamis értéket is eltárolhatunk.
Bizony, 32 igaz/hamis érték. Hiszen 1 integer változó 32 bitbõl áll, ha minden bitet hasznosítunk, akkor a bitmûveletek felhasználásával 32 igaz/hamis értéket is eltárolhatunk. Összehasonlítva:
32 darab boolean változó mérete 32 bájt. 1 integer változó mérete: 4 bájt.
Vagyis 32 boolean változó esetén nyolcad annyi memóriánkba kerül, ha egy darab integerben tároljuk el az értékeket. Persze 32 booleanra ritkán van szükség, de egy RP modban simán elõfordulhat. Gondoljunk csak bele...
Van 32 boolean-tömbös változónk, ez a maximum slotszámot(1000) figyelembe véve: 32*1000 byte azaz 32000 byte ami ~31 kilobyte.
Ha ezt egyetlen integer-tömbbel oldanánk meg: 4*1000 byte, azaz 4000 byte, ami ~3,9 kilobyte. Azért így nézve már nem annyira \"elhanyagolandó\" az a különbség szerintem =)
Akár írhatnánk erre külön egy függvényt, mely az adott bit értékével tér vissza. Nem is bonyolult. Így már azok számára is használhatóak a bitmûveletek, akik nem értenek hozzá, és rengeteg memóriát takaríthatnak meg.
Íme egy függvény az adatok kiolvasására:
stock GetData(integer, bit) { return integer >> bit & 1; //vagy az 1 helyett akár 0x01 alakban is megadhatjuk, nincs jelentõsége }
És a párja, adat írásra:
stock SetData(&integer, bit, value) { integer |= value << bit; return 1; }
Persze ezt még lehetne csinosítani, hogy pl. ne 0-tól hanem 1-tõl számoljuk a biteket, vagy hogy 31(vagy 32 ha 1-tõl számolunk) felett 0 legyen a return értéke, esetleg a value-re is rakhatnánk ellenõrzést, hogy 0-1-e az értéke, vagy más, de ilyenekkel most nem törõdtem.
2.6.3 Több érték, egy integerbe
Na ez az a rész, ami véleményem szerint már csak a nagyon megrögzött memóriafelszabadítók szerint nem lesz felesleges Amennyiben nincs szükségünk túl nagy számokra(pl. csak 0-15, vagy akár csak 0-7, de akár még a 0-255 is megfelel), akkor akár egy integerbe is tehetjük õket. Hogyan? Egyszerû. Csoportosítjuk a biteket. Tegyük fel, hogy maradván egy RP szervernél, el akarjuk tárolni ûbergigantikusan memóriakímélõ megoldással a játékos házának számát(ez legyen mondjuk 0-100 közötti szám), a játékos frakcióját(ez legyen 0-15 között), a játékos rangját(0-7 között), hogy a telefonja be van-e kapcsolva(0-1), a játékos szolgálati jármûvének id-jét(legyen 0-255 között), és az alapmunkáját(0-15 között). Ez is megoldható, egyetlen integerben, és ismételten 1000 slottal számolva máris megspóroltunk 4*4*1000+1*1000 byte-t(5 integer, és 1 boolean helyett csupán 1 integert használunk), ami ~16,6 kilobyte. Azért nem mindegy az, hogy 20,5 kb-ot vagy 4 kb-ot használunk szerintem...
Ezt a következõ módszerrel valósíthatnánk meg:
#define DATA_HOUSE 0 #define DATA_FACTION 1 #define DATA_RANK 2 #define DATA_PHONESTATE 3 #define DATA_DUTYCAR 4 #define DATA_JOB 5 stock GetData(playerinfo, data) { switch(data) { case DATA_HOUSE: return playerinfo & 127;//7 bit case DATA_FACTION: return playerinfo >> 7 & 15;//4 bit case DATA_RANK: return playerinfo >> 11 & 7;//3 bit case DATA_PHONESTATE: return playerinfo >> 14 & 1;//1 bit case DATA_DUTYCAR: return playerinfo >> 15 & 255;//8 bit case DATA_JOB: return playerinfo >> 23 & 15;//4 bit } return -1; } stock SetData(&playerinfo, data, value) { switch(data) { case DATA_HOUSE: { playerinfo = playerinfo & ~127 | value; }//7 bit (0-127 közötti maximálisan) case DATA_FACTION: { playerinfo = playerinfo & ~(15 << 7) | value << 7; }//4 bit (0-15 között) case DATA_RANK: { playerinfo = playerinfo & ~(7 << 11) | value << 11; }//3 bit (0-7 között) case DATA_PHONESTATE: { playerinfo = playerinfo & ~(1 << 14) | value << 14; }//1 bit (0-1) case DATA_DUTYCAR: { playerinfo = playerinfo & ~(255 << 15) | value << 15; }//8 bit (0-255 között) case DATA_JOB: { playerinfo = playerinfo & ~(15 << 23) | value << 23; }//4 bit (0-15 között) } return -1; } stock SetDatas(&playerinfo, house, faction, rank, phonestate, dutycar, job) { playerinfo |= house | (faction << 7) | (rank << 11) | (phonestate << 14) | (dutycar << 15) | (job << 23); }
Ez már azért elég morbid, ezt inkább csak érdekességképp mutattam, de éppenséggel ez is használható lenne, csak ehhez már kell egy kis õrültség
2.7 Második fejezet vége
Nos, láthattuk hogyan is mûködik mindazon sok \"marhaság\", amit az elsõ fejezetben elméletként átvettünk. Láthattuk hogyan mûködnek a jármûvek paneljének adataival babráló encode függvények, valamint megmutattam, hogyan írhatunk hozzájuk decode verziókat. Láthattunk még példát egyéb gyakorlati hasznosításra, kicsit megkoccoltuk a hexadecimális számok világát is, majd szóba került egy kis memóriatakarékosság. Végül mutattam egy összetettebb, elvetemült példát is, a bitmûveletek hasznosítására.
3. Összegzés, végszó Úgy gondolom, hogy elég részletesen körbe jártuk a témát. Megnéztük a bitmûveletek elméleti, és gyakorlati oldalát is, láthattunk gyakorlati példákat. Nem kell elsõre megérteni ezt az egészet, sõt... Elegendõ ha egyszer elolvassuk, emésztjük kicsit, majd késõbb megint elõvesszük, akkor netán már kicsit többet is megértünk belõle. Nem egy kihagyhatatlan része a Pawno-nak, de azért van annak haszna, ha az ember jártas ebben a témában is, bár sokak szerint nem éri meg a sok fáradtságot, és idõt, mely a megértéséhez, begyakorlásához, használatának elsajátításához szükséges. Próbáltam mindent részletesen kifejteni. A bonyolultabb dolgokhoz sokat magyarázni, az egyszerûbbek esetén csak visszautalni az alapokhoz. Sok dolgot talán már túl is magyaráztam. Ezt a leírást nem 1 nap alatt készítettem el, kb. 1 hónapja írtam meg az elméleti oldalát, most az elmúlt pár napban pedig a gyakorlatot. Esténként 1-2 órát szántam rá csupán, és mivel ilyenkor már nem vagyok épp a toppon, elképzelhetõ, hogy néhány helyen helyesírási, vagy elvi hibát vétettem. Amennyiben valaki ilyet találna, kérem szóljon, és korrigálni fogom. Nos, azt hiszem nincs is más hátra, mint hogy sok szerencsét kívánjak a bitmûveletek elsajátításához, és megosszam a forrásokat. Remélem néhányan hasznosnak találják, eme igen hosszúra sikerült leírást.
4. Források: Internet:
Könyv, e-book:
Pohl László - A programozás alapjai(BME - Elektronikus Eszközök Tanszéke, Budapest, 2010)
- Siroki László - C programozás - Bitmûveletek jegyzete
ˆ Anthony, 2012 - Minden jog fenntartva. A leírás egészben, vagy részleteiben szabadon terjeszthetõ, ameddig egyértelmûen fel van tüntetve az eredeti készítõ, valamint hogy honnan is származik.
580
« Dátum: 2012. július 27. - 20:27:36 »
a gamer laptopt se tud annyit. vagy esetleg megtudod fizetni? megéri egyáltalán annyi pénzért a gamer laptop? de a téma nem a laptop vs pc, hanem intel vagy amd.
Nem is mi kezdtük el szarozni a laptopokat
581
« Dátum: 2012. július 27. - 17:38:06 »
Van AMD-s asus, bõven. Viszont az csak barnában van. És mitõl lenne jobb az asus? Fõleg ha netán pl. ugyanaz van benne mint egy samsungba? konfigfüggõ. De pl. egy Razor Blade laptop...
582
« Dátum: 2012. július 27. - 14:05:58 »
Mégis lassan már több laptopot értékesítenek, mint asztalit ::| Abban egyet étek, hogy játékra jobb az asztali, ezt nem vitatom. \"Esélye sincs\" egy laptopnak, de azért tudnak meglepetést okozni... Nyilván nem játékra lettek kitalálva. De játékon kívül még rengeteg mindenre lehet használni egy gépet.
583
« Dátum: 2012. július 27. - 12:33:41 »
Nem értem miért nézi le mindenki ennyire a laptopokat. Azért ez az okostelefonos dolog megint eléggé túlzás... Sztem te sem gondoltad komolyan... Még ha tabletet mondasz, az is baromság, soká fogják még felvenni a versenyt a laptopokkal(most nem a 70 ezres Tesco gazdaságos laptopra kellene gondolni...). Egy okostelefon meg... Jó vicc Most direkt nem veszem \"magamra\" a szarozást, számomra egy laptop sokkal hasznosabb mint egy otthoni. És miért ne lehetne rajta programozni? Ne keverjük már notebookot a netbookal... Az egy dolog hogy intel atom 0,00009 GHz-s szutyok fél giga ramos 6 colos kijelzõs marhaság épp h az oprendszert elbírja, de azok netbookok... Ne keverjük össze a kettõt, mert nem sok közük van egymáshoz. Nyilván nem fogok 2 gépet \"fenntartani\", itthon egy asztalit, mikor hetente 2 napot vagyok itthon, a koliba meg laptopot, amit hordok órára is. Igen, 2 gépem van, de egyik sincs a \"toppon\". Mégsem találkoztam még olyan dologgal, amire ne lett volna jó mind a kettõ. És ne lenne jó a notebook programozásra, ettõl nem tudok elszakadni Miért? Mitõl nem képes egy notebook elfuttatni a Visual Studio-t, vagy egy devcpp-t? Esetleg nem kompatibilis XAMPP-vel és WAMPP-al, így már phpzni sem lehet rajta? Szeretem az ilyet, mikor benyögnek valami hasonlót... Ez olyan mint ha én meg rányögném, hogy asztalinál meg nem lehet ide-oda hurcibálni. Lehet, de nyilván nem ugyanaz a kettõ... Arról meg ne is beszéljünk, hogy melyiknek mennyi a fogyasztása... Lehet rámondani hogy szar, csak éppen negyedannyi fogyasztással hozza ki azt a \"szart\"... Csak épp ebbe kevesen szoktak belegondolni... Ja, hogy ennek nem annyi a fogyasztása? 3-ad annyi fogyasztásból hozza ki azt a bizonyos \"szar\" teljesítményt... Nyilván ha a laptopoknak is 6-700 W állna rendelkezésére, akkor nem ilyen lenne a teljesítmény... Szóval nem értem miért kellene egy laptopot egy asztalihoz hasonlítani bármilyen téren is, ennyi erõvel akkor hasonlítsuk a robogót a ferrarihoz... Ja, a Ferrari gyorsabb, csak kell mellé egy benzinkút is... Én meg a \"szaros\" laptopommal, csak röhögök, ha elmegy az áram Nem értem most hogy jött ide ez a laptop szarozás, de nem szeretem az ilyesmit. Miért kell egybõl így szar, úgy szar? Legalább ha alátámasztanád a véleményedet... Van egyáltalán laptopod? Netán több is mint 1? Mert ha nem, akkor ez most egy eléggé légbõl kapott, semmi konkrétumra nem épülõ HSZ volt
584
« Dátum: 2012. július 27. - 00:43:21 »
A trágyadomb, az az én egyéni véleményem, ezért is írtam úgy, hogy nem fogom számítógépnek nevezni. Miután vettem tõlük egy 35k-s procit, még évekkel ezelõtt, mikor a dualcore nagy szám volt, ami 5 alaplapban kipróbálva nem mûködött, majd visszaküldtük nekik, garanciával, és kiszúrták a szemem annyival, hogy õk nem tapasztaltak hibát a mûködésébe, hát elmehetnek a *********. Biztos sz*r az én alaplapom, haveromé, meg az a 3 amivel a boltba kipróbálták, reális... (mellesleg azóta is mûködik az az alaplap..) A másik Inteles proci ami itthon volt, az is egy csoda teremtmény volt... minden sz*rt kicseréltünk a gépbe, mondván egy 2 hónapos proci csak nem hibás, mire kiderült, hogy de, pont az a fos... Egy kalap sz*r volt az is, pedig az se 5000 volt, és 2 hónap után mehetett a kukába... Részemrõl kifizettem 2 prociért olyan 65-70k-t, és egyik sem mûködött (rendesen). Részemrõl ennyi, én többet rá se nézek intelre... Állítom garanciába rá se néztek, csak rávágták, hogy nincs vele gond. 5 alaplapban nem mûködik, de nekik meg jó... Hát jó, akkor adjon egy alaplapot, és mutassa meg, akkor elhiszem... De semmire nem megyek vele, azt mondanak amit akarnak. Ha azt mondják hogy mûködik, akkor ez van, ezt kell szeretni. Én úgy vagyok inkább összespórolok akkor inkább általában a jobbat és a drágábbat ezt megtanultam pár év alatt hogy így érhet a legkevesebb csalódás meglepetés fõleg nem egy processzorba spórolok.[/quote] Az én tapasztalatom, hogy édes mindegy, hogy megveszel egy pár hónapos modellt, vagy egy 3 naposat, ugyanúgy semmit sem fog érni kis idõ múlva, mert annyira piacorientált a technikai fejlõdés, hogy kénytelenek 2-3 havonta valami újít piacra dobni. Már persze az árához képest ki idõ múlva. És hogy válaszoljak a példádra, mitõl jobb a kokakóla mint a teszkós? Én úgy gondolom, ha ráköltök 300 ezret, akkor sem fog pár hónapnál tovább a \"top\"-on maradni. Mûködni ugyanúgy fog 5 év múlva is. Szóval nem értem ezt az 5 éves példát. Az új játékokat 3 év után már úgysem fogja rendesen vinni (tapasztalat, unokatesómnak anno olyan gépet vettünk, mikor egyetemre ment, h a legújabb játékokat fullon vitte, 3 év telt el azóta, most már semmit nem ér az a gép...), az operációs rendszer meg ugyanúgy fut egy rosszabb gépen is =) Most eddig próbáltam csak tapasztalatokat írni, próbálok ezután is annál maradni. Nekem az AMD vált be, egyszer sem volt még vele gondom, az elmúlt 5-6 év alatt. Bezzeg intellel... Most pl. szobatársam laptopot vett, ugyanolyat mint én, csak az egyel nagyobb \"családból\", meg intel+nvidia párosban. Még 20k-val többet is fizetett mint én. Azóta 2x volt szervízben a laptop, 1x beégett a procija, és teljes alaplapcsere volt, másodszor meghalt a hûtése (nem mondom hogy annak is köze lehet a dologhoz, hogy én jobban vigyázok rá mint õ, de akkor is...). Egy core i5-ös proci van benne, az enyémben pedig egy Phenom II X3-as. Papíron az övé a jobb, de gyakorlatban ez vagy nem érzõdik, vagy nagyon elrontott valamit, de akár játszunk, akár mást csinálunk, az enyém jobban szokta bírni a terhelést. (mondjuk videókártyám az erõsebb, de az nem hinném, h sokat közrejátszana, mikor programozunk ) Pár hete vett húgom egy laptopot. Igen, AMD-set. Õ mondta az árat, én pedig néztem a választékot. Direkt inteleset is néztem. Bementem ismerõshöz, számtech boltba, õ is az AMD-set ajánlotta(nála vettük, de neki az érte volna meg, ha a másikat ajánlja, mert az drágább lett vna). Választhattam a Llano és a DualCore között... Nos, mivel utóbbival felszerelt laptopoknak csodálkoznék ha egy film lejátszása nem okozna gondot, így én inkább azt mondtam, hogy a Llano legyen. Beépített vidikari nem egy atomreaktor, ezzel tisztában vagyok. De, néztem tesztet, amiben összehasonlítottak 9-10 laptopot, nem emlékszem pontosan, ami 130k alatt volt. Egyetlen egy laptop volt, aminek a grafikus teljesítménye meghaladta az 5 FPS-t, és Dirt, és Crysys alatt produkált játszható FPS-t.. Nos, egyértelmû volt számomra, hogy jobban megéri a Llano, hisz bármikor jól jöhet egy normális VGA. Nyilván játszani nem igazán fog vele, de azért ne haljon már bele a gép egy Autocad futtatásába, vagy egy egyszerû filmnézésbe... Arról nem is beszélve, hogy aksi üzemidõben normál terheléssel dupláját bírta az inteles \"csodáknak\", terhelés alatt pedig igencsak középmezõnyben volt.(azonos kapacitású akkumulátorok voltak) Kinek mi vált be, nyilván függ a hardverkörnyezettõl, vagy hogy mire használja a gépet, no meg hogy mennyire \"rendetlen\", és rakja tele minden sz*r csilivili szutyokkal az asztalt, 4000 bõvítménnyel a böngészõt, meg 200 kis méretben futó, winfossal induló alkalmazással... Számomra az volt fontos, hogy jó akkumlátor üzemidõvel, egy olyan notit vegyek, ami árban is megéri, aksi ideje is megfelelõ, és éppen-éppen elfutnak rajta az új játékok is. Nem akartam gamer notit, mert én már kinõttem ebbõl a nagyon játékos korszakból. Január óta alig játszottam, inkább netezek, beszélgetek... És legfõképp nem is érte volna meg, nem használnám ki, nem vagyok annyira játék centrikus. GTA IV is csak a multija miatt van fent, mert jókat lehet vele LAN-ozni. Ott van benne a kismillió féle játékmód, így nem kell 8 játékot feltenni. És mivel noti, még könnyedén hurcibálom is. Buszon filmet nézek, de éppen olyan is volt már, h pawnoztam, vagy php-ztam3 óra körüli aksi idõ legtöbbször elegendõ. Úgy gondolom jól döntöttem, ha én is a \"nagytesót\" veszem, akk 20k+ba került volna, egy intel i5-ös procival, gyengébb videó kártyával... Én többet egy vasat nem költök inteles cuccra, hogy aztán megint valami sz*rt adjanak, ami vagy nem mûködik, vagy meghal 2 hónap után
585
« Dátum: 2012. július 26. - 23:05:33 »
Mennyi hülyeség van itt xD Elõször is az emberi szem 16 képkocka/mp felett már mozgóképnek érzékel bármit. Az, hogy a ti szemetek hozzá van szokva a 7000 FPS-hez, nem azt jelenti, hogy annyi kell a folyamatos futáshoz... És attól hogy a filmtechnikában 24 FPS a szabvány(hangsúlyozom, filmtechnika!), attól még miért lenne szabvány egy számítógépes játékban? Ez am alapból hülyeség, mivel a szem ígyis-úgyis érzékeli az FPS változást, már ha olyan határon belül van, amit még érzékelni képes. Ezért van, hogy ha a GTA IV \"beszaggat\" 60 FPS-en, az lehet hogy csak 30-ra esett le, ami alapjában véve még mindig normális, nem? Másrészrõl, az hogy ki mit \"lát\" mozgóképnek, az nem az FPS-tõl függ. Nekem pl laptopon fix 30 FPS-el fut a GTA IV, és mégis szaggat. Most akkor hogy is van ez? Vagy én vagyok hülye, vagy a progi csal, de az akkor is szaggat...(és nem, nem FRAPS-el néztem...) A másik h a BF3 nem indul 2 magos AMD-n Ezen nagyot néztem... Hozzászoktam, hogy az intelesek ilyen-olyan dolgokat terjesztenek az AMD-rõl, de ez azért már elég nagy hülyeség El kell keserítselek, Athlon X2-es AMD-men, egy szaros HD4670-es vidikarival végigtoltam 1680*1050-es felbontásban a játékot Nem fullon, de nem is minimumon. Más: az, hogy hány FPS-t produkál egy játék, sokkal kisebb mértékben függ a procitõl, mint a videó kártyától (már persze ésszerû keretek között). Szal lehet itt példálózni, hogy ennyi-annyi FPS, lehetnek szar beállítások, szutyok driver, szar hûtés, koszolódás, bármi... Vagy netán videókártya... Adhatsz egy 8 magos proci mellé és GeForce 4 MX 440-et, nem fog GTA IV-t vinni, pont úgy, ahogy a Celeron D 3.0 GHz-s proci se fogja egy HD7970-el vinni... Olyan párosítás kell, ahol hasonlóan erõs a két hardver, hogy egyik se fogja vissza a másikat. Másképp csak vár az egyik a másikra.... Vagy a proci nem fogja tudni kihajtani a vidikarit, vagy a vidikarit fogja visszafogni a proci... Egyébként meg ez most olyan, hogy ha az intel csinál egy tesztet, én is mindenbe belekötnék, még a székek színébe, meg a betûk nagyságába is, csak mert intel. Szóval másolgatni lehet teszteket egymásnak, csak felesleges. Ez csak egy vitatéma lesz megint. Senki nem fogja a másikat meggyõzni. Engem senki nem fog meggyõzni, hogy Intelt vegyek, soha a büdös életbe nem fogom számítógépnek nevezni az olyan trágyadombokat, amiben intel van. De ugyanígy, én sem gyõzöm meg pl. Gentlemant, hogy AMD-t vegyen, mert õ meg Intel fanatikus. Ennyi. És lehet érvelni, de felesleges. Lehet teszteket mutogatni, lehet 4 éves procit összehasonlító 2 hónapossal, és fordítva, értelmetlen. Nálam nem egy papírdarab dönti el, hogy mit veszek, hanem adott ár alatt a legolcsóbbat. (pl. itt van ez a \"hülye\" i5-ös szutyok, amivel állandóan példálóztok. Igen, \"csak\" 50k. De én komplett gépet raktam össze 60-ból 2 éve, és még most is megy rajta a GTA IV, BF3...). Ki mennyit szán rá (bár én ha 400k-t szánnék rá se tennék bele intelt, mert egy életre meggyûlöltem a pénzéhes mocskokat). Van akinek az számít, hogy minél jobb legyen, van akinek meg hogy minél jobb, egy adott ár alatt. Nyilván 60k-ból nem hozol össze egy igazi gamer konfigot, de egy igazi gamerbe nem is i5-ös proci lenne... Van aki 4-5 évet spórol, és rászán 200k-t, és akk \"csak\" 50-60k jut procira, más meg egy nyarat ledolgozik, összeszed 150-200k-t, abból ezt-azt vesz, és 60k-t szán gépre. Nem kívánok beszállni ebbe a veszekedésbe, felesleges. Senki sem gyõzi meg a másikat, ebben biztos vagyok. Lehet itt pattogni, hogy Így intel, meg úgy AMD, senki nem egy netes fórum miatt fog úgy dönteni ahogy... Én speciel ha veszek valamit, akk elõször is megnézem mennyit szánok rá. Ha az megvan, akk a maximumtól -20%-ig elkezdem nézegetni mi a kínálat. Ami ránézésre legjobbnak tûnik 5-6 darab, arról nézek tesztet, hátha van összehasonlítási alap (hál istennek egy árkategóriába szokott lenni), és aztán a legjobbat veszem, ami a keretbe belefér. Nekem ez így megy. És bár baromi ritkán játszom 60 FPS-el, de legalább nem idegelem magam, hogy 1 hónapos játék nem megy fullon a 2 hónapos gépemen És itt most senkit nem akartam megsérteni, de egyesek úgy \"harcolnak\" az igazukért ilyen témában állandóan, hogy az már-már szektás fanatizmusra emlékeztet Utoljára még egy jó tanács: ne mindig higgyünk a teszteknek. És legfõképp, ameddig nincs valamiról megbízható információnk(de jobb a tapasztalat), addig inkább na akarjunk bele érvelni. Ezt most csak azért mondom, mert volt itt pár olyan HSz, hogy \"az AMD ezt nem tudja, az AMD azt nem tudja...\" Kipróbáltátok? Nem. Akkor? Én is kereshetek olyan tesztet, amit pl. egy hibás intellel csináltak, és máris úgy állíthatom be, hogy nekem van igazam. Az a gond itt, hogy a legtöbben nem tudnak úgy érvelni, hogy az ÉRVEK pártatlanok maradjanak. Az érv ne úgy legyen már érv, hogy kiforgatjuk a szavakat, hogy nekünk legyen igazunk...
Oldalak: 1 ... 37 38 [39] 40 41 ... 79
|