Bitové operátory a operátory posunutí (referenční informace jazyka C#)
Následující operátory provádějí bitové operace nebo operace posunutí s operandy celočíselného typu nebo typu char:
- Unární
~operátor (bitový doplněk) - Binární
<<operátory posunutí (posun doleva)>>a (posun doprava) - Binární
&operátory (logické operátory AND),|logické operátory ORa^(logické výhradní operátory OR)
Tyto operátory jsou definovány pro int typy , , a uint long ulong . Pokud jsou oba operandy jiného celočíselného typu ( , , , , nebo ), jejich hodnoty jsou převedeny na typ , což je také výsledný sbyte byte typ short ushort char int operace. Pokud jsou operandy různých integrálních typů, jejich hodnoty jsou převedeny na nejbližší obsahující celočíselné typy. Další informace najdete v části Číselné povýšení specifikace jazyka C#.
Operátory , a & | jsou také ^ definovány pro operandy bool typu. Další informace najdete v tématu Logické logické operátory.
Bitové operace a operace posunutí nikdy nezpůsobí přetečení a v zaškrtnutém a nezaškrtnutém kontextu nevytvářely stejné výsledky.
Operátor bitového doplňku ~
Operátor vytváří bitový doplněk svého ~ operandu tím, že reverzní každý bit:
uint a = 0b_0000_1111_0000_1111_0000_1111_0000_1100;
uint b = ~a;
Console.WriteLine(Convert.ToString(b, toBase: 2));
// Output:
// 11110000111100001111000011110011
Symbol můžete použít také ~ k deklaraci finalizačních metod. Další informace najdete v tématu Finalizační metody.
Operátor posunu doleva <<
Operátor posune svůj levý operand doleva o počet << bitů definovanýchjeho operandem na pravé straně .
Operace posunu vlevo zahodí bity vyššího řádu, které jsou mimo rozsah výsledného typu, a nastaví pozice prázdných bitů nízkého řádu na nulu, jak ukazuje následující příklad:
uint x = 0b_1100_1001_0000_0000_0000_0000_0001_0001;
Console.WriteLine($"Before: {Convert.ToString(x, toBase: 2)}");
uint y = x << 4;
Console.WriteLine($"After: {Convert.ToString(y, toBase: 2)}");
// Output:
// Before: 11001001000000000000000000010001
// After: 10010000000000000000000100010000
Vzhledem k tomu, že operátory posunutí jsou definovány pouze pro typy , , a , obsahuje výsledek operace vždy int uint alespoň long ulong 32 bitů. Pokud je levý operand jiného celočíselného typu ( , , , nebo ), jeho hodnota je převedena na typ, jak ukazuje sbyte byte následující short ushort char int příklad:
byte a = 0b_1111_0001;
var b = a << 8;
Console.WriteLine(b.GetType());
Console.WriteLine($"Shifted byte: {Convert.ToString(b, toBase: 2)}");
// Output:
// System.Int32
// Shifted byte: 1111000100000000
Informace o tom, jak pravý operand operátoru definuje počet směn, najdete v části Počet směn << operátorů posunutí.
Operátor posunu doprava >>
Operátor posune svůj levý operand doprava o počet >> bitů definovanýchjeho operandem na pravé straně .
Operace posunu doprava zahodí bity nízkého řádu, jak ukazuje následující příklad:
uint x = 0b_1001;
Console.WriteLine($"Before: {Convert.ToString(x, toBase: 2), 4}");
uint y = x >> 2;
Console.WriteLine($"After: {Convert.ToString(y, toBase: 2), 4}");
// Output:
// Before: 1001
// After: 10
Prázdné bitové pozice vyššího řádu jsou nastaveny na základě typu levého operandu následujícím způsobem:
Pokud je levý operand typu nebo , operátor posunu doprava provede aritmetický posun: hodnota nejvýznamnějšího bitu
intlong(bit znaménka) levého operandu se rozšíří na pozice prázdného bitu vyššího řádu. To znamená, že pozice prázdného bitu vyššího řádu jsou nastaveny na nulu, pokud je levý operand nezá záporný, a na hodnotu 1, pokud je záporný.int a = int.MinValue; Console.WriteLine($"Before: {Convert.ToString(a, toBase: 2)}"); int b = a >> 3; Console.WriteLine($"After: {Convert.ToString(b, toBase: 2)}"); // Output: // Before: 10000000000000000000000000000000 // After: 11110000000000000000000000000000Pokud je levý operand typu nebo , operátor posunu doprava provede logický posun: pozice prázdného bitu vyššího řádu jsou vždy nastaveny
uintulongna nulu.uint c = 0b_1000_0000_0000_0000_0000_0000_0000_0000; Console.WriteLine($"Before: {Convert.ToString(c, toBase: 2), 32}"); uint d = c >> 3; Console.WriteLine($"After: {Convert.ToString(d, toBase: 2), 32}"); // Output: // Before: 10000000000000000000000000000000 // After: 10000000000000000000000000000
Informace o tom, jak pravý operand operátoru definuje počet směn, najdete v části Počet směn >> operátorů posunutí.
Logický operátor AND &
Operátor & vypočítá bitový logický operátor AND svých celočíselné operandy:
uint a = 0b_1111_1000;
uint b = 0b_1001_1101;
uint c = a & b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 10011000
Pro bool operandy & operátor vypočítá logický operátor AND svých operandů. Unární & operátor je operátor adresy.
Logický exkluzivní operátor OR ^
Operátor vypočítá bitový logický exkluzivní operátor OR, označované také ^ jako bitový logický XOR, jeho integrálních operandů:
uint a = 0b_1111_1000;
uint b = 0b_0001_1100;
uint c = a ^ b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 11100100
Pro bool operandy operátor ^ vypočítá logický exkluzivní operátor OR svých operandů.
Logický operátor OR |
Operátor | vypočítá bitový logický operátor OR svých celočíselné operandy:
uint a = 0b_1010_0000;
uint b = 0b_1001_0001;
uint c = a | b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 10110001
Pro bool operandy | operátor vypočítá logický operátor OR svých operandů.
Složené přiřazení
Výraz složeného přiřazení formuláře pro op binární operátor
x op= y
je ekvivalentem
x = x op y
s tím x rozdílem, že se vyhodnocuje jenom jednou.
Následující příklad ukazuje použití složeného přiřazení s bitovými operátory a operátory posunutí:
uint INITIAL_VALUE = 0b_1111_1000;
uint a = INITIAL_VALUE;
a &= 0b_1001_1101;
Display(a); // output: 10011000
a = INITIAL_VALUE;
a |= 0b_0011_0001;
Display(a); // output: 11111001
a = INITIAL_VALUE;
a ^= 0b_1000_0000;
Display(a); // output: 1111000
a = INITIAL_VALUE;
a <<= 2;
Display(a); // output: 1111100000
a = INITIAL_VALUE;
a >>= 4;
Display(a); // output: 1111
void Display(uint x) => Console.WriteLine($"{Convert.ToString(x, toBase: 2), 8}");
Z důvodu číselných povýšenínemusí být výsledek operace op implicitně převoditelný na T typ x . Pokud je v takovém případě předdefinovaný operátor a výsledek operace je explicitně převoditelný na typ , je výraz složeného přiřazení formuláře ekvivalentní s tím rozdílem, že se vyhodnotí pouze op T x x op= y x = (T)(x op y) x jednou. Toto chování je znázorněno v následujícím příkladu:
byte x = 0b_1111_0001;
int b = x << 8;
Console.WriteLine($"{Convert.ToString(b, toBase: 2)}"); // output: 1111000100000000
x <<= 8;
Console.WriteLine(x); // output: 0
Priorita operátorů
V následujícím seznamu jsou seřazeny bitové operátory a operátory posunu počínaje nejvyšší prioritou na nejnižší:
- Operátor bitového doplňku
~ - Operátory posunutí
<<a>> - Logický operátor AND
& - Logický exkluzivní operátor OR
^ - Logický operátor OR
|
Pomocí závorek změňte pořadí vyhodnocení () vynucované prioritou operátorů:
uint a = 0b_1101;
uint b = 0b_1001;
uint c = 0b_1010;
uint d1 = a | b & c;
Display(d1); // output: 1101
uint d2 = (a | b) & c;
Display(d2); // output: 1000
void Display(uint x) => Console.WriteLine($"{Convert.ToString(x, toBase: 2), 4}");
Úplný seznam operátorů jazyka C# seřazených podle úrovně priority najdete v části Priorita operátorů v článku Operátory jazyka C#.
Počet směn operátorů posunutí
Pro operátory posunu a musí být typ operandu na pravé straně nebo typ, který má předdefinovaný << >> implicitní číselný int převod na int .
U x << count x >> count výrazů a závisí skutečný počet směn na následujícím x typu:
Pokud je typ nebo , je počet směn definovaný pěti
xintuintbity pravého operandu v nízkém pořadí. To znamená, že počet směn se počítá zcount & 0x1F(nebocount & 0b_1_1111).Pokud je typ nebo , je počet posunů definován šesti
xlongulongbity pravého operandu v nízkém pořadí. To znamená, že počet směn se počítá zcount & 0x3F(nebocount & 0b_11_1111).
Toto chování je znázorněno v následujícím příkladu:
int count1 = 0b_0000_0001;
int count2 = 0b_1110_0001;
int a = 0b_0001;
Console.WriteLine($"{a} << {count1} is {a << count1}; {a} << {count2} is {a << count2}");
// Output:
// 1 << 1 is 2; 1 << 225 is 2
int b = 0b_0100;
Console.WriteLine($"{b} >> {count1} is {b >> count1}; {b} >> {count2} is {b >> count2}");
// Output:
// 4 >> 1 is 2; 4 >> 225 is 2
Poznámka
Jak ukazuje předchozí příklad, výsledek operace posunutí může být nenulový, i když je hodnota pravého operandu větší než počet bitů v levém operandu.
Výčet logických operátorů
Operátory ~ , , a jsou také podporovány & | ^ libovolným typem výčtu. Pro operandy stejného typu výčtu je provedena logická operace s odpovídajícími hodnotami základního integrálního typu. Například pro jakýkoli a typu výčtu s podkladovým typem vytvoří výraz stejný x y výsledek jako výraz T U x & y (T)((U)x & (U)y) .
Obvykle se používají bitové logické operátory s typem výčtu, který je definován atributem Flags. Další informace najdete v části Výčtové typy jako bitové příznaky v článku Typy výčtů.
Přetížení operátoru
Uživatelem definovaný typ může přetížit ~ operátory , << , , , a >> & | ^ . Při přetížení binárního operátoru je také implicitně přetížen odpovídající složený operátor přiřazení. Uživatelem definovaný typ nemůže explicitně přetížit složený operátor přiřazení.
Pokud uživatelem definovaný typ přetěžuje operátor nebo , musí být typ levého operandu a typ T << >> T pravého operandu musí být int .
specifikace jazyka C#
Další informace najdete v následujících částech specifikace jazyka C#: