Bites működés - Bitwise operation
A számítógép-programozás , a bitenkénti művelet működik egy bitsorozat , egy kicsit tömb vagy bináris szám (tekinteni bitsorozat) szintjén az egyes bitek . Ez egy gyors és egyszerű művelet, amely a magasabb szintű aritmetikai műveletek alapja, és amelyet közvetlenül a processzor támogat . A legtöbb bitenkénti művelet két operandusú utasításként jelenik meg, ahol az eredmény felváltja az egyik bemeneti operandust.
Egyszerű, alacsony költségű processzorok esetén a bitenkénti műveletek jellemzően lényegesen gyorsabbak, mint az osztás, többször gyorsabbak, mint a szorzások, és néha lényegesen gyorsabbak, mint az összeadás. Míg a modern processzorok rendszerint ugyanolyan gyorsan hajtják végre az összeadást és a szorzást, mint a bitenkénti műveletek a hosszabb utasításcsövek és más építészeti tervezési lehetőségek miatt, addig a bitenkénti műveletek általában kevesebb energiát fogyasztanak a csökkentett erőforrás -felhasználás miatt.
Bitenkénti operátorok
Az alábbi magyarázatokban a bit pozíciójának bármely jelzése a jobb (legkevésbé szignifikáns) oldalról számítódik balra. Például a 0001 bináris érték (decimális 1) minden helyzetben nulla, kivéve az elsőt (azaz a jobb szélsőt).
NEM
A bitenkénti NOT vagy a komplementer egy unáris művelet, amely logikai tagadást hajt végre minden biten, és az adott bináris érték komplementjét képezi. A 0 bitből 1 lesz, az 1 -esből 0 lesz. Például:
NOT 0111 (decimal 7) = 1000 (decimal 8)
NOT 10101011 (decimal 171) = 01010100 (decimal 84)
A bitenkénti kiegészítés megegyezik az érték mínusz egy komplementerével . Ha két komplement aritmetikát használunk, akkor NOT x = -x − 1
.
Az előjel nélküli egész számok esetében a szám bitenkénti kiegészítése a szám "tükörreflexiója" az előjel nélküli egész tartomány tartományának félúton. Például 8 bites előjel nélküli egész számok esetében NOT x = 255 - x
, amelyek egy grafikonon lefelé mutató vonalként jeleníthetők meg, amelyek hatékonyan "elfordítják" a növekvő tartományt 0-ról 255-re, a csökkenő tartományra 255-ről 0-ra. Egy egyszerű, de szemléltető példa egy szürkeárnyalatos kép invertálása, ahol minden képpont alá nem írt egész számként van tárolva.
ÉS
A bitenkénti ÉS egy bináris művelet , amely két egyenlő hosszúságú bináris ábrázolást vesz fel, és elvégzi a logikai ÉS műveletet a megfelelő bitek minden párján, ami egyenértékű azok megszorzásával. Így ha az összehasonlított helyzetben lévő mindkét bit 1, akkor a kapott bináris ábrázolás bitje 1 (1 × 1 = 1); ellenkező esetben az eredmény 0 (1 × 0 = 0 és 0 × 0 = 0). Például:
0101 (decimal 5) AND 0011 (decimal 3) = 0001 (decimal 1)
A művelet segítségével megállapítható, hogy egy adott bit beállítása (1) vagy törlés (0). Például, ha egy 0011 bitmintát adunk meg (decimális 3), annak meghatározásához, hogy a második bit be van -e állítva, használunk bitenkénti ÉS bites mintát, amely csak 1 -et tartalmaz a második bitben:
0011 (decimal 3) AND 0010 (decimal 2) = 0010 (decimal 2)
Mivel a 0010 eredmény nem nulla, tudjuk, hogy az eredeti minta második bitjét állítottuk be. Ezt gyakran bitmaszkolásnak nevezik . ( Hasonlóképpen a maszkolószalag -borítók vagy maszkok használata , amelyeket nem szabad megváltoztatni, vagy olyan részek, amelyek nem érdekesek. Ebben az esetben a 0 értékek elfedik azokat a biteket, amelyek nem érdekesek.)
A bitenkénti ÉS felhasználható a regiszter kiválasztott bitjeinek (vagy zászlóinak ) törlésére , amelyben minden bit egy egyedi Boole -állapotot képvisel . Ez a technika hatékony módszer számos Boole -érték tárolására a lehető legkevesebb memória felhasználásával.
Például a 0110 (tizedes tizedes) négy zászlóból álló halmaznak tekinthető, ahol az első és a negyedik zászló világos (0), a második és a harmadik pedig (1). A harmadik zászlót törölni lehet bitenkénti ÉS használatával, azzal a mintával, amelynek csak a harmadik bitje van nulla:
0110 (decimal 6) AND 1011 (decimal 11) = 0010 (decimal 2)
Ennek a tulajdonságnak köszönhetően egyszerűvé válik a bináris szám paritásának ellenőrzése a legalacsonyabb értékű bit értékének ellenőrzésével. A fenti példa segítségével:
0110 (decimal 6) AND 0001 (decimal 1) = 0000 (decimal 0)
Mivel a 6 ÉS 1 nulla, a 6 osztható kettővel, és ezért páros.
VAGY
A bitenkénti VAGY egy bináris művelet , amely két azonos hosszúságú bitmintát vesz fel, és végrehajtja a logikai befogadó VAGY műveletet minden megfelelő bitpáron. Az eredmény minden pozícióban 0, ha mindkét bit 0, míg különben az eredmény 1. Például:
0101 (decimal 5) OR 0011 (decimal 3) = 0111 (decimal 7)
A bitenkénti VAGY használható a fent leírt regiszter kiválasztott bitjeinek 1 -re állítására. Például a 0010 negyedik bitje (decimális 2) beállítható úgy, hogy bites sorrendben VAGY a mintát csak a negyedik bitkészlettel hajtjuk végre:
0010 (decimal 2) OR 1000 (decimal 8) = 1010 (decimal 10)
XOR
A bitenkénti XOR egy bináris művelet , amely két azonos hosszúságú bitmintát vesz fel, és elvégzi a logikai kizáró VAGY műveletet minden megfelelő bitpáron. Az eredmény minden pozícióban 1, ha a bitek közül csak az egyik 1, de 0 lesz, ha mindkettő 0 vagy mindkettő 1. Ebben két bit összehasonlítását hajtjuk végre, 1, ha a két bit különbözik, és 0 ha egyformák. Például:
0101 (decimal 5) XOR 0011 (decimal 3) = 0110 (decimal 6)
A bitenkénti XOR használható a kiválasztott bitek invertálásához egy regiszterben (más néven toggle vagy flip). Bármelyik bit átváltható XOR -mal 1 -gyel. Például, tekintettel a 0010 -es bitmintára (decimális 2), a második és a negyedik bit egy bit szerinti XOR -val átváltható egy bitmintával, amely 1 -et tartalmaz a második és a negyedik pozícióban:
0010 (decimal 2) XOR 1010 (decimal 10) = 1000 (decimal 8)
Ez a technika használható a logikai állapotok halmazait reprezentáló bitminták manipulálására.
Az összeszerelési nyelv programozói és az optimalizáló fordítók néha az XOR-t használják gyorsbillentyűként a regiszter értékének nullára állításához . Ha az XOR értéket önmagával szemben hajtja végre, mindig nulla lesz, és sok architektúránál ez a művelet kevesebb óraciklust és memóriát igényel, mint egy nulla érték betöltése és a regiszterbe mentése.
Ha a rögzített n hosszúságú bitsorozatok halmazát (azaz gépi szavakat ) n -dimenziós vektortérnek tekintjük a mező felett , akkor a vektorösszegzés megfelel a bitenkénti XOR -nak.
Matematikai megfelelői
Feltéve , hogy a nem negatív egész számokra vonatkozóan a bitenkénti műveletek a következőképpen írhatók fel:
Igazságtábla minden bináris logikai operátorhoz
Két bináris változónak 16 lehetséges igazságfüggvénye van ; ez egy igazságtáblázatot határoz meg .
Íme két P és Q bit bitben egyenértékű művelete:
o | q | F 0 | NOR 1 | Xq 2 | ¬p 3 | ↛ 4 | ¬q 5 | XOR 6 | NAND 7 | ÉS 8 | XNOR 9 | q 10 | Ha/akkor 11 | 12. o | Akkor/ha 13 | VAGY 14 | T 15 | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | ||
1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | ||
0 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | ||
0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | ||
Bites egyenértékűek |
0 |
NEM (p VAGY q) |
(NEM p) ÉS q |
NEM p |
p ÉS (NEM q) |
NEM q |
p XOR q |
NEM (p ÉS q) |
p ÉS q |
NEM (p XOR q) |
q |
(NEM p) VAGY q |
o |
p VAGY (NEM q) |
p VAGY q | 1 |
Bit eltolódások
A biteltolásokat néha bitenkénti műveleteknek tekintik, mivel az értékeket bitek sorozataként kezelik, nem pedig numerikus mennyiségként. Ezekben a műveletekben a számjegyeket balra vagy jobbra mozgatják vagy eltolják . A számítógépes processzorban lévő regiszterek rögzített szélességűek, így néhány bit az egyik végén "eltolódik" a regiszterből, míg a másik végből ugyanannyi bit "eltolódik"; A biteltolásos operátorok közötti különbségek abban rejlenek, hogy hogyan határozzák meg az átvitt bitek értékeit.
Bitcímzés
Ha a regiszter szélessége (gyakran 32 vagy akár 64) nagyobb, mint a legkisebb címezhető egység (atomi elem) bitjeinek száma (általában 8), amelyet gyakran bájtnak neveznek, az eltolási műveletek címzési sémát indukálnak a bájtokról a bitek. Ezáltal a "bal" és "jobb" tájolást a számok szabványos helyérték -jelölésű írásából vesszük , úgy, hogy a bal eltolás növekszik, a jobb eltolás pedig csökkenti a szám értékét-ha először a bal számjegyeket olvassuk be big-endian orientációt alkot . Figyelmen kívül hagyva a határhatásokat a regiszter mindkét végén, az aritmetikai és a logikai eltolási műveletek ugyanúgy viselkednek, és a 8 bites pozícióval történő eltolás a bitmintát 1 bájtos pozícióval szállítja a következő módon:
|
a bal oldali eltolás 8 pozícióval növeli a bájtcímet 1 -gyel |
|
a jobb oldali eltolás 8 pozícióval csökkenti a bájtcímet 1 -gyel |
|
a bal oldali eltolás 8 pozícióval csökkenti a bájtcímet 1 -gyel |
|
a jobb oldali eltolás 8 pozícióval 1 -el növeli a bájtcímet |
Aritmetikai eltolás
Egy aritmetikai , a bitek tolódnak ki mindkét végén elöntjük. Bal aritmetikai eltolásnál a nullák eltolódnak a jobb oldalon; Egy jobb aritmetikai, az előjel bit (MSB ketteskomplenens) el van tolódva a bal oldalon, és így megőrzi a jel az operandus.
Ez a példa egy 8 bites regisztert használ, amelyet két kiegészítőként értelmeznek:
00010111 (decimal +23) LEFT-SHIFT = 00101110 (decimal +46)
10010111 (decimal −105) RIGHT-SHIFT = 11001011 (decimal −53)
Az első esetben a bal szélső számjegy eltolódott a regiszter végén, és egy új 0 került a jobb szélső helyzetbe. A második esetben a jobb szélső 1 -et eltolták (talán a hordozó zászlóba ), és egy új 1 -et másoltak át a bal szélső helyzetbe, megőrizve a szám jelét. A több műszakot néha egyetlen műszakra rövidítik le néhány számjeggyel. Például:
00010111 (decimal +23) LEFT-SHIFT-BY-TWO = 01011100 (decimal +92)
A bal oldali számtani eltolás n -vel egyenlő 2 n -gyel való szorzással (feltéve, hogy az érték nem túlcsordul ), míg a kettes komplement értékének jobb oldali számtani eltolása n -vel egyenlő az osztás emeletének 2 n -vel történő felvitelével . Ha a bináris számot komplementerként kezeljük , akkor ugyanez a jobbra tolási művelet 2 n- el osztást és nulla felé kerekítést eredményez .
Logikai váltás
A logikai váltás során a nullákat eltolják a kidobott bitek helyett. Ezért a logikai és a számtani bal eltolódás pontosan ugyanaz.
Mivel azonban a logikai jobbra tolás 0 bit értéket szúr be a legjelentősebb bitbe, az előjelbit másolása helyett ideális az előjel nélküli bináris számokhoz, míg a jobb oldali aritmetikai eltolás ideális az aláírt kettes komplementer bináris számokhoz.
Körkörös eltolás
Egy másik formája a váltás a gyűrűs eltolási , bitenkénti forgás vagy kicsit forgatás .
Forog
Ebben a műveletben, amelyet néha rotate no carry -nek is neveznek , a biteket úgy forgatják el, mintha a regiszter bal és jobb vége kapcsolódna egymáshoz. A bal eltolás során jobbra tolható érték az, amit a bal oldalon eltoltunk, és fordítva, jobb műveletek esetén. Ez akkor hasznos, ha a meglévő biteket meg kell őrizni, és gyakran használják a digitális titkosításban .
Forgatás a hordozáson keresztül
Az elforgatás a hordozáson keresztül a forgatási művelet egyik változata, ahol a (mindkét végén) eltolt bit a hordozójelző régi értéke, és a (másik végén) eltolt bit lesz az új érték a hordozó zászlót.
Egyetlen elforgatás a hordozáson keresztül szimulálhatja egy pozíció logikai vagy számtani eltolódását, ha előzetesen beállítja a hordozási zászlót. Például, ha a hordozási zászló 0-t tartalmaz, akkor x RIGHT-ROTATE-THROUGH-CARRY-BY-ONE
logikus jobbra tolás, és ha a hordozási zászló a jelbit másolatát tartalmazza, akkor x RIGHT-ROTATE-THROUGH-CARRY-BY-ONE
aritmetikai jobb eltolás. Emiatt egyes mikrovezérlők, például az alacsony kategóriájú PIC -k csak forognak és forognak a hordozáson keresztül , és nem zavarják a számtani vagy logikai váltási utasításokat.
Az elforgatás a hordozáson keresztül különösen akkor hasznos, ha a processzor natív szóméreténél nagyobb számokkal hajt végre műszakot , mert ha nagy számot tárolunk két regiszterben, akkor az első regiszter egyik végéről eltolt bitnek be kell jönnie a másik végén. a második. Az elforgatás-átvitelnél ez a bit az első műszak során "mentésre" kerül a hordozási zászlóba, és készen áll a második műszakban történő bekapcsolásra minden további előkészítés nélkül.
Magas szintű nyelveken
C-család
A C-család nyelveiben a logikai váltó operátorok " <<
" a bal és " >>
" a jobb váltáshoz. A kezelő második argumentumaként a váltandó helyek számát adja meg. Például,
x = y << 2;
a balra x
való eltolás eredményét y
két bittel rendeli hozzá , ami egyenlő a négyes szorzással.
A váltások a megvalósítás által meghatározott viselkedést vagy nem definiált viselkedést eredményezhetnek , ezért használatuk során körültekintően kell eljárni. A szó méreténél nagyobb vagy azzal megegyező bitszámmal történő eltolás eredménye a C és C ++ nyelvekben meghatározott viselkedés. A negatív érték jobbra tolása a megvalósítás által meghatározott, és a jó kódolási gyakorlat nem ajánlja; az aláírt érték balra tolásának eredménye nem definiált, ha az eredmény nem ábrázolható az eredménytípusban.
A C#-ban a jobb eltolás aritmetikai eltolás, ha az első operandus int vagy long. Ha az első operandus uint vagy ulong típusú, akkor a jobbra tolás logikai eltolás.
Körkörös eltolódások
A nyelvek C-családjából hiányzik a rotációs operátor (bár a C ++ 20 biztosítja std::rotl
és std::rotr
), de az egyik szintetizálható a shift operátorokból. Gondoskodni kell arról, hogy a nyilatkozat jól formázott legyen, hogy elkerüljük a biztonsági követelményekkel rendelkező szoftverekben a nem meghatározott viselkedést és az időzítési támadásokat . Például egy naiv megvalósítás bal forog egy 32 bites előjel nélküli érték x
által n
pozíciók egyszerűen:
uint32_t x = ..., n = ...;
uint32_t y = (x << n) | (x >> (32 - n));
Ha azonban eltolódás által 0
bitek eredménye definiálatlan viselkedése a jobb oldali kifejezés (x >> (32 - n))
, mert 32 - 0
van 32
, és 32
kívül esik a tartományon [0 - 31]
beleértve. Egy második próbálkozás következményei lehetnek:
uint32_t x = ..., n = ...;
uint32_t y = n ? (x << n) | (x >> (32 - n)) : x;
ahol a műszak összegét tesztelik annak biztosítása érdekében, hogy ne vezessen be meghatározatlan viselkedést. Az ág azonban további kódútvonalat ad hozzá, és lehetőséget kínál az időzítés elemzésére és a támadásra, ami gyakran nem elfogadható a nagy integritású szoftverekben. Ezenkívül a kód több gépi utasítást is összeállít, ami gyakran kevésbé hatékony, mint a processzor natív utasítása.
A GCC és a Clang alatti meghatározatlan viselkedés és ágak elkerülése érdekében az alábbiakat javasoljuk. A mintát sok fordító felismeri, és a fordító egyetlen forgatási utasítást ad ki:
uint32_t x = ..., n = ...;
uint32_t y = (x << n) | (x >> (-n & 31));
Léteznek fordítóspecifikus belső jellemzők is, amelyek körkörös váltásokat hajtanak végre , például _rotl8, _rotl16 , _rotr8, _rotr16 a Microsoft Visual C ++ -ban . A Clang néhány forgatható tulajdonságot biztosít a Microsoft -kompatibilitáshoz, amely a fenti problémákkal küzd. A GCC nem kínál rotációs belső tulajdonságokat. Az Intel x86 Intrinsics -t is biztosít .
Jáva
A Java , minden egész típusú aláírta, így a „ <<
” és „ >>
” operátorok Aritmetikai műszakban. A Java hozzáadja a " >>>
" operátort a logikai jobb eltolások végrehajtásához, de mivel a logikai és aritmetikai balra tolási műveletek megegyeznek az aláírt egész számokkal, nincs " <<<
" operátor a Java-ban.
A Java shift operátorok további részletei:
- Az üzemeltetők
<<
(bal shift),>>
(aláírt jobb shift), és>>>
(unsigned jobb shift) nevezik műszak szereplők . - A shift kifejezés típusa a bal oldali operandus előléptetett típusa. Például
aByte >>> 2
egyenértékű .((int) aByte) >>> 2
- Ha a bal oldali operandus promotált típusa int, akkor csak a jobb oldali operandus öt legalacsonyabb rendű bitjét használjuk eltolási távolságként. Mintha a jobb oldali operandust bitenkénti logikai ÉS operátor alá vetnénk, és 0x1f (0b11111) maszkértékkel. A ténylegesen használt váltási távolság ezért mindig 0 és 31 között van.
- Ha a bal oldali operandus promotált típusa hosszú, akkor csak a jobb oldali operandus hat legalacsonyabb rendű bitjét használjuk eltolási távolságként. Mintha a jobb oldali operandust bitenkénti logikai ÉS operátor alá vetnénk, és 0x3f (0b111111) maszkértékkel. A ténylegesen használt váltási távolság ezért mindig 0 és 63 között van.
- A értéke
n >>> s
az n jobb eltolt s bithelyeit nulla-hosszabbító. - A bit- és shift műveleteknél a típus
byte
implicit módon átalakulint
. Ha a bájt értéke negatív, a legmagasabb bit egy, akkor az egyesek az int -ben lévő további bájtok kitöltésére szolgálnak. Tehát azt eredményezi .byte b1 = -5; int i = b1 | 0x0200;
i == -5
JavaScript
A JavaScript bitenkénti műveleteket alkalmaz két vagy több egység 1 -es vagy 0 -ás helyének értékelésére .
Pascal
A Pascal -ban, valamint minden dialektusában (például Object Pascal és Standard Pascal ) a logikai bal és jobb shift műveletek " shl
" és " shr
". Még aláírt egész számok esetén is shr
logikai eltolódásként viselkedik, és nem másolja az előjelet. Második érvként a váltandó helyek számát adjuk meg. Például az alábbiak x -et rendelnek hozzá az y bal oldali eltolásához két bittel:
x := y shl 2;
Egyéb
- popcount , kriptográfia
- számolja a vezető nullákat
Alkalmazások
Bitenkénti műveletekre van szükség különösen alacsonyabb szintű programozásban, például eszközillesztőkben, alacsony szintű grafikákban, kommunikációs protokoll csomagok összeállításában és dekódolásában.
Bár a gépek gyakran hatékony beépített utasításokkal rendelkeznek az aritmetikai és logikai műveletek végrehajtásához, mindezek a műveletek végrehajthatók a bitenkénti operátorok kombinálásával és a nulla tesztelés különböző módjaival. Például itt van az ókori egyiptomi szorzás pszeudokódos megvalósítása, amely bemutatja, hogyan lehet megszorozni két tetszőleges egész számot ( és nagyobb, mint ) csak biteltolások és összeadások használatával:
a
b
a
b
c ← 0
while b ≠ 0
if (b and 1) ≠ 0
c ← c + a
left shift a by 1
right shift b by 1
return c
Egy másik példa a pszeudokódját végrehajtása mellett, amely bemutatja, hogyan kell kiszámítani az összeg két egész szám a
, és b
segítségével bitműveletek és nulla vizsgálata:
while a ≠ 0
c ← b and a
b ← b xor a
left shift c by 1
a ← c
return b
Logikai algebra
Néha hasznos egyszerűsíteni a bitenkénti műveletekből álló összetett kifejezéseket. Például fordítók írásakor. A fordító célja egy magas szintű programozási nyelv lefordítása a lehető leghatékonyabb gépi kódra . A Boole -algebra a bonyolult bites kifejezések egyszerűsítésére szolgál.
ÉS
x & y = y & x
x & (y & z) = (x & y) & z
x & 0xFFFF = x
x & 0 = 0
x & x = x
VAGY
x | y = y | x
x | (y | z) = (x | y) | z
x | 0 = x
x | 0xFFFF = 0xFFFF
x | x = x
NEM
~(~x) = x
XOR
x ^ y = y ^ x
x ^ (y ^ z) = (x ^ y) ^ z
x ^ 0 = x
x ^ y ^ y = x
x ^ x = 0
x ^ 0xFFFF = ~x
Ezenkívül az XOR a 3 alapművelet segítségével állítható össze (ÉS, VAGY, NEM)
a ^ b = (a | b) & (~a | ~b)
a ^ b = (a & ~b) | (~a & b)
Mások
x | (x & y) = x
x & (x | y) = x
~(x | y) = ~x & ~y
~(x & y) = ~x | ~y
x | (y & z) = (x | y) & (x | z)
x & (y | z) = (x & y) | (x & z)
x & (y ^ z) = (x & y) ^ (x & z)
x + y = (x ^ y) + ((x & y) << 1)
x - y = ~(~x + y)
Inverzek és egyenletek megoldása
Nehéz lehet megoldani a logikai algebra változóit, mert a normál algebrával ellentétben több műveletnek nincs inverze. Az inverz nélküli műveletek végrehajtásuk során elveszítik az eredeti adatbitek egy részét, és ez a hiányzó információ nem állítható helyre.
- Inverz van
- NEM
- XOR
- Forgasd balra
- Forgasd jobbra
- Nincs fordított
- ÉS
- VAGY
- Shift balra
- Shift jobbra
Műveletek sorrendje
A lista elején található műveleteket hajtják végre először. Tekintse meg a fő cikket a teljes listához.
( )
~ -
* / %
+ -
<< >>
&
^
|
Lásd még
Hivatkozások
Külső linkek
- Az online Bitwise számológép támogatja a Bitwise AND, OR és a XOR értékeket
- Osztás bitshifts segítségével
- " Bitwise Operations Mod N ", Enrique Zeleny, Wolfram Demonstrations Project .
- „ Parcellák készítmények Bitorientált Operations ” Enrique Zeleny, a Wolfram bemutatók Project.