Bitsel operatörler. Bit düzeyinde işlemler

  • 20.04.2019

bitsel operatörler

C # bir dizi sağlar bitsel operatörler C # kullanabileceğiniz görev aralığını genişleten. Bitsel operatörler, işlenenlerinin bireysel ikili rakamları (bitleri) üzerinde hareket eder. Yalnızca tamsayı işlenenleri için tanımlanırlar, bu nedenle bool, float veya double türündeki verilere uygulanamazlar.

Bu operatörler denir bit düzeyinde bir tamsayı değeri oluşturan bitleri kontrol etmeye, ayarlamaya veya kaydırmaya hizmet ettikleri için. Diğer şeylerin yanı sıra, en çok çözmek için bitsel operatörler kullanılır. farklı görevlerörneğin cihaz durum bilgilerinin analizi dahil olmak üzere sistem düzeyinde programlama. C#'da bulunan tüm bitsel operatörler aşağıda listelenmiştir:

Bitsel operatörler AND, OR, özel OR ve NOT

Bitsel operatörler AND, OR, özel OR ve NOT belirtilir Aşağıdaki şekilde: &, |, ^ ve ~. Mantıksal karşılıklarıyla aynı işlevleri yerine getirirler. Ancak mantıksal operatörlerin aksine, bitsel operatörler tek tek ikili bitler düzeyinde çalışır.

En yaygın uygulamanın bakış açısından, bitsel AND işlemi, tek tek ikili basamakları bastırmanın bir yolu olarak düşünülebilir. Bu, işlenenlerden herhangi birinin herhangi bir biti 0 ise, sonuçtaki karşılık gelen bitin 0'a sıfırlanacağı anlamına gelir. VEYA operatörü bireysel ikili rakamları ayarlamak için kullanılabilir. Bu operatörün herhangi bir işlenenindeki herhangi bir bit 1'e ayarlanırsa, diğer işlenendeki karşılık gelen bit de 1'e ayarlanır. bit düzeyinde özel VEYA operatörü işlenenin ikili bitini, ancak ve ancak, aşağıdaki örnekte olduğu gibi, karşılaştırılan işlenenlerin ikili basamakları farklıysa ayarlar. Yukarıdakileri anlamak için aşağıdaki örneği inceleyin:

Şimdi bitsel operatörleri kullanan örnek bir programa bakalım:

Sistemi Kullanmak; System.Collections.Generic kullanarak; System.Linq kullanarak; System.Text'i kullanarak; namespace ConsoleApplication1 (sınıf Program (static void Main (string args) (chet (16); provChet (8); nechet (16); Console.ReadLine ();) // Tüm tek sayıları çift sayıya dönüştüren yöntem // // kullanarak aralık bitsel operatör& static void chet (int x) (int sonuç; Console.WriteLine ("0'dan (0)'a dönüştürülmüş sayı aralığı: \ n", x); for (int i = 0; i

Vardiya operatörleri

C#, bir tamsayı değeri oluşturan ikili basamakları belirli bir miktarda sola veya sağa kaydırma özelliğine sahiptir. Bu operatörler için genel form aşağıdadır:

anlam
değer >> bit sayısı

burada num_bits, belirtilen değerin kaydırıldığı ikili basamak sayısıdır.

Sola kaydırıldığında, belirtilen değerdeki tüm ikili basamaklar bir konum sola kaydırılır ve en az anlamlı bit sıfıra temizlenir. Sağa kaydırma, belirtilen değerdeki tüm ikili basamakları bir konum sağa kaydırır. İşaretsiz bir tamsayı değeri sağa kaydırılırsa, en anlamlı bit sıfırlanır. Ve işaretli bir tamsayı değeri sağa kaydırılırsa, işaret biti korunur. Negatif sayıları temsil etmek için bir tamsayının en anlamlı bitinin 1'e ayarlandığını hatırlayın. Dolayısıyla, kaydırılacak değer negatifse, sağa her kaydırmada sayının en anlamlı biti 1'e ayarlanır. Kaydırılan değer pozitifse, sağa yapılan her kaydırma ile sayının en önemli biti sıfırlanır.

Etiketler: C bit işlemleri, bit düzeyinde işlemler, bit düzeyinde toplama, bit düzeyinde çarpma, bit sola kaydırma, bit sağa kaydırma

Tanıtım

I dili C'ye bazen demir özlemi nedeniyle makro derleyici denir. Optimizasyon kullanmazsanız, program kodunun montaj dilinde hangi yapılara dönüştürüleceğini kabaca tahmin edebilirsiniz. Dilin sadeliği ve minimalizmi (dilin sadeliği, dilde programlamanın basitliği ile karıştırılmamalıdır), birçok platformda C'nin tek olduğu gerçeğine yol açtı. üst düzey dil programlama. İnceleme yok bitsel işlemler elbette, dil öğrenimi eksik olacaktır.

Bitsel işlemler, adından da anlaşılacağı gibi, doğrudan bitlerle işlem yapmanızı sağlar. Çok sayıda bitsel işlemleri kullanma örnekleri, örneğin Henry Warren'ın Programcılar için Algoritmik Hileler kitabında bulunabilir. Burada sadece işlemleri ve ilkel algoritmaları ele alacağız.

Bit düzeyinde VE, VEYA, DEĞİL, özel VEYA

Başlangıç ​​için hatırlatayım mantıksal işlemler AND, OR, özel OR ve NOT doğruluk tabloları kullanılarak tanımlanabilir

Mantıksal operatör DEĞİL
x X DEĞİL
0 1
1 0

Bit bazında işlemlerde, 1 bit değeri mantıksal doğru, 0 ise yanlış olarak kabul edilir. Bitsel AND (& operatörü) iki sayı alır ve karşılık gelen bitleri mantıksal olarak çarpar. Örneğin, 3 ile 8'i mantıksal olarak çarparsak 0 elde ederiz.

Karakter a = 3; karakter b = 8; karakter c = a & b; printf ("% d", c);

İkili olduğundan, tek baytlık bir tamsayı olarak 3

c değişkeninin ilk biti, a sayısının ilk biti ile b sayısının ilk bitinin mantıksal çarpımına eşittir. Ve böylece her bit için.

00000011
00001000
↓↓↓↓↓↓↓↓
00000000

Buna göre, 31 ve 17 sayılarının bitsel çarpımı, 31'in 00011111 ve 17'nin 00010001 olması nedeniyle 17'yi verecektir.

00011111
00010001
↓↓↓↓↓↓↓↓
00010001

35 ve 15 sayılarının bitsel çarpımı 3'tür.

00100011
00001111
↓↓↓↓↓↓↓↓
00000011

Bitsel VEYA işlemi (işleci |), sayıların karşılık gelen bitlerini taşımadan mantıksal olarak toplaması dışında benzer şekilde çalışır.

Örneğin,

Karakter a = 15; karakter b = 11; karakter c = bir | B; printf ("% d", c);

15 çıktısı olacak, çünkü 15 00011111 ve 11 00001011

00001111
00001011
↓↓↓↓↓↓↓↓
00001111

33 ve 11 sayıları için bitsel VEYA, 33, 00100001 ve 11, 00001011 olduğundan 43 döndürür.

00100001
00001011
↓↓↓↓↓↓↓↓
00101011

Bitsel olumsuzlama (işleci ~) tek bir bit için değil, tam sayı için çalışır. Ters çevirme operatörü, her bit için yanlışı doğruya ve doğruyu yanlışa değiştirir. Örneğin,

Karakter a = 65; karakter b = ~ a; printf ("% d", b);

65 01000001 olduğundan -66 çıktısı olacak ve tersi 10111110 verecek

hangisi -66. Bu arada, bir sayıyı negatif yapmak için bir algoritma: bulmak ek kod sayıları ters çevrilmeli ve bir tane eklenmelidir.

Karakter a = 107; karakter b = ~ a + 1; printf ("a = %d, -a = %d", a, b);

Özel VEYA (operatör ^) bit düzeyinde bir XOR işlemi uygular. Örneğin, sayılar için

Karakter a = 12; karakter b = 85; karakter c = bir ^ b; printf ("% d", c);

a 00001100 ve b 01010101 olduğundan 89 çıktısı alınacaktır. Sonuç olarak, 01011001 elde ederiz.

Ara sıra mantıksal operatörler&& ve || & ve | operatörleriyle karıştırılır. Bu tür hatalar kodda uzun süre kalabilir, çünkü bu tür kodlar bazı durumlarda çalışacaktır. Örneğin, 1 ve 0 sayıları için. Ancak si'de sıfır olmayan herhangi bir değer doğru olduğundan, mantıksal çarpmanın doğru döndürmesi gerekse de, 3 ve 4 sayılarının bit düzeyinde çarpımı 0 döndürür.

Int a = 3; int b = 4; printf ("a & b =% d \ n", a & b); // 0 yazdırır printf ("a && b =% d \ n", a && b); // 0 değil (daha spesifik olarak 1) yazdırır

Bitsel kaydırma işlemleri

İki kaydırma işlemi - bit sola kaydırma (operatör<<) и битовый сдвиг вправо (оператор >>). Bit düzeyinde sağa kaydırma, bir sayının bitlerini sağa kaydırır ve sola sıfırlar ekler. Sola biraz kaydırma tam tersini yapar: bitleri sola kaydırır, sağa sıfırlar ekler. Aralık dışı bitler atılır.

Örneğin, 5 sayısını 2 konum sola kaydırın

00000101 << 2 == 00010100

19 sayısını 3 pozisyon sağa kaydır

00010011 >> 3 == 00000010

Mimariden bağımsız olarak (big-endian veya küçük-endian veya orta-endian), ikili sayılar soldan sağa, daha fazla önemli bit daha az önemli olana. Bit düzeyinde kaydırma iki işlenen alır - kaydırılacak sayı ve kaydırılacak bit sayısı.

Int a = 12; printf ("% d<< 1 == %d\n", a, a << 1); printf("%d << 2 == %d\n", a, a << 2); printf("%d >> 1 ==% d \ n ", a, a >> 1); printf ("% d >> 2 ==% d \ n ", a, a >> 2);

Sağa kaydırma (>>) soldan sıfırlar eklediğinden, tamsayılar için işlem şuna eşittir: tamsayı bölümü yarısı ve sola kaydırma 2 ile çarpılır. Açık bir tür dönüşümü olmadan kayan noktalı bir sayı için bit kaydırma yapmak mümkün değildir. Bunun nedeni, C'nin tanımlanmış bir kayan nokta gösterimine sahip olmamasıdır. Ancak, numarayı taşıyabilirsiniz batmadan yüzmek int'ye, sonra kaydırmaya ve geri dönmeye

Şamandıra b = 10.0f; float c = (float) (* ((işaretsiz int *) & b) >> 2); printf ("%. 3f >> 2 =% .3f", b, c);

Ama elbette 5.0f almayacağız, tamamen farklı bir sayı alacağız.

Vardiya operatörlerinin özel bir özelliği, derleyiciye bağlı olarak işaretli ve işaretsiz sayılarla farklı davranabilmeleridir. Yok canım, negatif bir sayı genellikle bir işaret biti içerir. Sola kaydırma yaptığımızda kaybolabilir, sayı pozitif olur. Ancak derleyici kaymayı sabit tutabilir ve farklı kuralları takip edebilir. Aynı şey sağa kayma için de geçerli.

İmzasız int ua = 12; imzalı int sa = -11; printf ("ua =% d, ua >> 2 =% d \ n", ua, ua >> 2); printf ("sa =% d, sa >> 2 = % d \ n", sa, sa >> 2); printf ("(imzasız) sa =% u, sa >> 2 =% u \ n", sa, sa >> 2); printf ("sa =% d, ((işaretsiz) sa) >> 2 = % d", sa, ((işaretsiz) sa) >> 2);

V bu durum ilk vardiyada her şey istendiği gibi çalışır, çünkü sayı işaretsizdir. İkinci durumda, VSE2013 derleyicisi işareti bırakır. Ancak bu sayının işaretsiz bir sayı olarak temsiline bakarsanız, en soldaki bit korunarak kaydırma farklı kurallara göre gerçekleşir. Son satırda, imzalı bir sayıyı imzasız bir sayıya getirirseniz, normal kayma meydana gelir ve sonuç olarak pozitif bir sayı elde ederiz.

Bitsel ve kaydırma operatörleri bir sayının değerini değiştirmez ve yenisini döndürür. Onlar da tıpkı aritmetik operatörler, karmaşık bir görevin parçası olabilir

Int a = 10; int b=1; a >> = 3; bir ^ = (b<< 3); и т.д.

Örnekleri

1. Bir sayının belirli bir bitini belirlememize ve değiştirmemize izin veren fonksiyonlar yazalım.

Hangi bitin (1 veya 0) n konumunda olduğunu bulmak için mantıksal çarpma kullanacağız.

9 sayısı olsun

00001001

Bitin 3 konumunda (sıfırdan başlayarak) ayarlanıp ayarlanmadığını öğrenmeniz gerekir. Bunu yapmak için, üçüncü hariç tüm bitlerin sıfır olduğu bir sayı ile çarpın:

00001001 & 00001000 = 00001000

Şimdi 6. konumdaki bitin değerini öğreniyoruz.

00001001 & 01000000 = 00000000

Böylece, sıfıra eşit bir yanıt alırsak, istenen konum sıfır, aksi halde bir olur. İstenen konumda bir biti olan sıfırlardan oluşan bir sayı elde etmek için, gerekli sayıda biti 1 sola kaydırın.

#Dahil etmek #Dahil etmek #Dahil etmek int checkbit (const int değeri, const int konumu) (int sonucu; if ((değer & (1)<< position)) == 0) { result = 0; } else { result = 1; } return result; } void main() { int a = 3; size_t len = sizeof(int) * CHAR_BIT; size_t i; for (i = 0; i < len; i++) { printf("%d", checkbit(a, i)); } _getch(); }

Fonksiyonda koşulun şu şekilde yazıldığını unutmayın.

(değer & (1<< position)) == 0

Çünkü parantezler olmadan önce sıfıra eşitlik hesaplanacak ve ancak ondan sonra çarpma işlemi yapılacaktır.

Değer & (1<< position) == 0

İşlev basitleştirilebilir

Int checkbit (const int değeri, const int konumu) (dönüş ((değer & (1<< position)) != 0); }

n'inci konumdaki biti bire ayarlayan bir işlev.

Herhangi bir bitin 1'e mantıksal olarak eklenmesinin 1'e eşit olacağı bilinmektedir. Bu nedenle, n'inci biti ayarlamak için, mantıksal olarak, gerekli olan dışındaki tüm bitlerin eşit olduğu bir sayı eklemeniz gerekir. sıfır. Böyle bir sayının nasıl elde edileceği zaten tartışıldı.

Int setbit (sabit int değeri, sabit int konumu) (dönüş (değer | (1)<< position)); }

n'inci konumdaki biti sıfıra ayarlayan bir işlev.

Bunu yapmak için, n'inci hariç, sayının tüm bitlerinin değişmemesi gerekir. Sayıyı, numaralandırılmış bit dışında tüm bitlerin bire eşit olduğu bir ile çarpın. Örneğin

0001011 & 1110111 = 0000011

Böyle bir maske elde etmek için önce sıfır ve bir birim içeren bir sayı oluşturun ve ardından bunu ters çevirin.

Int unsetbit (sabit int değeri, sabit int konumu) (dönüş (değer & ~ (1<< position)); }

n'inci bitin değerini tersine çeviren bir işlev.

Bunu yapmak için özel veya işlevi kullanırız: XOR işlemini istenen bit yerine bir sıfır ve bir sıfırdan oluşan bir sayıya uygularız.

Int anahtar biti (sabit int değeri, sabit int konumu) (dönüş (değer ^ (1<< position)); }

muayene

#Dahil etmek #Dahil etmek #Dahil etmek int checkbit (const int değeri, const int konumu) (dönüş ((değer & (1<< position)) != 0); } int setbit(const int value, const int position) { return (value | (1 << position)); } int unsetbit(const int value, const int position) { return (value & ~(1 << position)); } int switchbit(const int value, const int position) { return (value ^ (1 << position)); } void printbits(int n) { //CHAR_BIT опеределён в библиотеке limits.h //и хранит число бит в байте для данной платформы size_t len = sizeof(int)* CHAR_BIT; size_t i; for (i = 0; i < len; i++) { printf("%d", checkbit(n, i)); } printf("\n"); } void main() { int a = 3; size_t len = sizeof(int) * CHAR_BIT; size_t i; printbits(a); a = setbit(a, 5); printbits(a); a = unsetbit(a, 5); printbits(a); a = switchbit(a, 11); printbits(a); a = switchbit(a, 11); printbits(a); _getch(); }

Bit bayrakları

Sentetik bir örnek düşünelim. Diyelim ki üç boole değişkenimiz var ve tüm bu değişkenlere bağlı olarak aynı anda belirli bir değer vermemiz gerekiyor. Açıkçası, 2 3 olası seçenek olabilir. Bu koşulu bir dal şeklinde yazalım:

#Dahil etmek int main () (işaretsiz char a, b, c; a = 1; b = 0; c = 0; if (a) (if (b) (if (c) (printf ("true true true"));) else (printf ("doğru doğru yanlış"));)) else (if (c) (printf ("doğru yanlış doğru"));) else (printf ("doğru yanlış yanlış");))) else (if (b) (if (c) (printf ("yanlış doğru doğru"));) else (printf ("yanlış doğru yanlış");)) else (if (c) (printf ("yanlış yanlış doğru"));) else (printf ( "yanlış yanlış yanlış");))) _getch (); 0 döndür;)

8 şubemiz var. Şimdi bir koşul daha eklememiz gerektiğini varsayalım. Daha sonra şube sayısı iki katına çıkacak ve programın anlaşılması ve hatalarının ayıklanması daha da zorlaşacaktır. Örneği yeniden yazalım.

Mantıksal değerlerimizin her biri, bit sayısı ile sola kaydırılır ve mantıksal olarak eklenirse, a, b ve c değerlerine bağlı olarak kendi benzersiz bit kombinasyonumuzu elde ederiz:

#Dahil etmek #Dahil etmek void printbits (int n) (int i; for (i = CHAR_BIT - 1; i> = 0; i--) (printf ("% d", (n & (1))<< i)) != 0); } printf("\n"); } int main() { unsigned char a, b, c; unsigned char res; a = 1; b = 0; c = 0; res = c | b << 1 | a << 2; printbits(res); a = 0; b = 1; c = 1; res = c | b << 1 | a << 2; printbits(res); a = 1; b = 0; c = 1; res = c | b << 1 | a << 2; printbits(res); _getch(); return 0; }

Bu yaklaşımı görevimizde kullanalım ve dallanmayı switch ile değiştirelim:

#Dahil etmek int ana () (işaretsiz karakter a, b, c; işaretsiz karakter res; a = 1; b = 0; c = 0; res = c | b<< 1 | a << 2; switch (res) { case 0b00000000: printf("false false false"); break; case 0b00000001: printf("false false true"); break; case 0b00000010: printf("false true false"); break; case 0b00000011: printf("false true true"); break; case 0b00000100: printf("true false false"); break; case 0b00000101: printf("true false true"); break; case 0b00000110: printf("true true false"); break; case 0b00000111: printf("true true true"); break; } _getch(); return 0; }

Bu yöntem, genellikle farklı programlama dillerindeki işlevlere seçenekler atamak için kullanılır. Her bayrak benzersiz bir ad alır ve bunların birleşik anlamı, kullanılan tüm bayrakların mantıksal toplamıdır. Örneğin, fcntl kitaplığı.

Bu sayfadaki bölümler:

bitsel operatörler

C # bir dizi sağlar bit düzeyinde C # kullanabileceğiniz görev aralığını genişleten operatörler. Bitsel operatörler, işlenenlerinin bireysel ikili rakamları (bitleri) üzerinde hareket eder. Yalnızca tamsayı işlenenleri için tanımlanırlar, bu nedenle bool, float veya double türündeki verilere uygulanamazlar.

Bu operatörler denir bit düzeyinde bir tamsayı değeri oluşturan bitleri kontrol etmeye, ayarlamaya veya kaydırmaya hizmet ettikleri için. Diğer şeylerin yanı sıra, bitsel operatörler, örneğin bir cihazın durumu hakkındaki bilgileri analiz etmek de dahil olmak üzere, sistem düzeyinde çok çeşitli programlama problemlerini çözmek için kullanılır. C#'da bulunan tüm bitsel operatörler Tablo 1'de listelenmiştir. 4.1.

Tablo 4.1. bitsel operatörler

Operatör Anlamı
& Bit düzeyinde VE
| Bit düzeyinde VEYA
^ Bit düzeyinde özel VEYA
>> Sağa kaydır
<< Sol shift
~ 1'in tamamlayıcısı (birli NOT operatörü)

Bitsel operatörler AND, OR, özel OR ve NOT

Bitsel operatörler AND, OR, özel OR ve NOT, &, |, ^ ve ~ olarak gösterilir. Yukarıda tartışılan mantıksal karşılıklarıyla aynı işlevleri yerine getirirler. Ancak mantıksal operatörlerin aksine, bitsel operatörler tek tek ikili bitler düzeyinde çalışır. Aşağıda ikili birler ve sıfırlarla yapılan bitsel işlemlerin sonuçları verilmiştir.

p q R & Q p | q p ^ q ~ p
0 0 0 0 0 1
1 0 0 1 1 0
0 1 0 1 1 1
1 1 1 1 0 0

En yaygın uygulamanın bakış açısından, bitsel AND işlemi, tek tek ikili basamakları bastırmanın bir yolu olarak düşünülebilir. Bu, işlenenlerden herhangi birinin herhangi bir biti 0 ise, sonucun karşılık gelen bitinin 0'a sıfırlanacağı anlamına gelir. Örneğin:

1101 0011
1010 1010
&_________
1000 0010

Aşağıdaki program örneği, tek sayıları çift sayılara dönüştürmek için bitsel & operatörünün kullanımını gösterir. Bunun için sayının en az anlamlı basamağını sıfırlamak yeterlidir. Örneğin, 9 sayısı aşağıdaki ikili biçime sahiptir: 0000 1001. Bu sayının en az anlamlı bitini temizlerseniz, o zaman 8 sayısı olur ve ikili biçimde - 0000 1000 olur.

// Sayıyı çift yapmak için bitsel AND operatörünü uygulayın.
Sistemi kullanarak;
sınıf MakeEven (
statik boşluk Ana () (
kısa numara; ushort i;
için (i = 1; ben<= 10; i++) {
sayı = ben;

num = (ushort) (sayı & 0xFFFE);
Console.WriteLine ("düşük sipariş bitini temizledikten sonraki sayı:"
+ sayı + "n");
}
}
}

sayı: 1
en az anlamlı biti temizledikten sonra num: 0
sayı: 2

sayı: 3
en az anlamlı biti temizledikten sonra num: 2
sayı: 4

sayı: 5
en az anlamlı biti temizledikten sonra num: 4
sayı: 6

sayı: 7
en az anlamlı biti temizledikten sonra num: 6
sayı: 8

sayı: 9
en az anlamlı biti temizledikten sonra num: 8
sayı: 10
en az anlamlı biti temizledikten sonra num: 10

Bitsel AND operatöründe kullanılan onaltılık değer 0xFFFE, aşağıdaki ikili forma sahiptir: 1111 1111 1111 1110. Böylece, bitsel AND işlemi, num'un sayısal değerindeki tüm bitleri, en az anlamlı bit dışında değişmeden bırakır; sıfır. Sonuç olarak, çift sayılar herhangi bir değişikliğe uğramaz ve tek sayılar 1 azalır ve çift olur.

Bitsel AND operatörü, tek bir bitin ayarlanmış veya temizlenmiş durumunu belirlemek için de kullanışlıdır. Aşağıdaki program örneği, bir sayının tek olup olmadığını belirler.

// olup olmadığını belirlemek için bitsel AND operatörünü uygulayın
// sayının tek olup olmadığı.
Sistemi kullanarak;
sınıf IsOdd (
statik boşluk Ana () (
kısa numara;
sayı = 10;
if ((sayı & 1) == 1)
Console.WriteLine ("Görüntülenmiyor.");
sayı = 11;
if ((sayı & 1) == 1)
Console.WriteLine (num + "tek bir sayıdır.");
}
}

Bu programın çıktısı böyle görünüyor.

11 tek sayıdır.

Yukarıdaki programdan her iki if ifadesinde de, num ve 1'in sayısal değerleri üzerinde bir bitsel AND işlemi gerçekleştirilir. bir ikili 1 içeriyorsa, bitsel işlem num & 1'in sonucu 1'e eşittir. Aksi takdirde, sıfıra eşittir. Bu nedenle, i f operatörü, yalnızca kontrol edilen sayının tek olduğu ortaya çıkarsa başarılı bir şekilde yürütülebilir.

Bitsel & operatörünü kullanarak bireysel ikili rakamların durumunu kontrol etme yeteneği, kontrol edilen bayt değerinin bireysel ikili rakamlarının ikili forma dönüştürüldüğü bir program yazmak için kullanılabilir. Böyle bir program yazmanın bir yolu aşağıda gösterilmiştir.

// Bir baytı oluşturan bitleri göster.
Sistemi kullanarak;
sınıf ShowBits (
statik boşluk Ana () (
int t;
bayt değeri;
değer = 123;
(t = 128; t> 0; t = t / 2) için (


}
}
}

Bu programı çalıştırmak aşağıdaki sonucu verir.

0 1 1 1 1 0 1 1

Yukarıdaki programdaki for döngüsü, bitin ayarlanmış mı yoksa temizlenmiş mi olduğunu görmek için bir bitsel AND operatörü kullanarak her bir val bitini inceler. Ayarlanmışsa 1 sayısı görüntülenir, silinirse 0 sayısı görüntülenir.

Bitsel OR operatörü, bireysel ikili basamakları ayarlamak için kullanılabilir. Bu operatörün herhangi bir işlenenindeki herhangi bir bit 1'e ayarlanırsa, diğer işlenendeki karşılık gelen bit de 1'e ayarlanır. Örneğin:

1101 0011
1010 1010
|_________
1111 1011

Bitsel VEYA operatörünü kullanarak, yukarıdaki tekten çifte program örneğini, çift sayıların tek sayılara dönüştürüldüğü aşağıdaki ters örneğe kolayca dönüştürebilirsiniz.

// Sayıyı tek yapmak için bit düzeyinde OR operatörü uygulayın.
Sistemi kullanarak;
sınıf MakeOdd (
statik boşluk Ana () (
kısa numara;
ushort i;
için (i = 1; ben<= 10; i++) {
sayı = ben;
Console.WriteLine ("sayı:" + sayı);
sayı = (ushort) (sayı | 1);
Console.WriteLine ("en az anlamlı biti ayarladıktan sonraki sayı:"
+ sayı + "n");
}
}
}

Bu programın sonucu aşağıdaki gibidir.

sayı: 1
en az anlamlı biti ayarladıktan sonra num: 1
sayı: 2

sayı: 3
en az anlamlı biti ayarladıktan sonra num: 3
sayı: 4

sayı: 5
en az anlamlı biti ayarladıktan sonra num: 5
sayı: 6

sayı: 7
en az anlamlı biti ayarladıktan sonra num: 7
sayı: 8

sayı: 9
en az anlamlı biti ayarladıktan sonra num: 9
sayı: 10
en az anlamlı biti ayarladıktan sonra num: 11

Yukarıdaki program, 1, en az anlamlı bitin ayarlandığı ikili değeri verdiğinden, num ve 1 değişkeninin her sayısal değeri üzerinde bit düzeyinde VEYA işlemi gerçekleştirir. 1 ve diğer herhangi bir değer üzerindeki bitsel VEYA işleminin bir sonucu olarak, diğer tüm bitler değişmeden kalırken, ikincisinin en az anlamlı biti ayarlanır. Bu nedenle, orijinal değer çift ise, elde edilen sayısal değer tektir.

Bit düzeyinde özel VEYA operatörü, aşağıdaki örnekte olduğu gibi, yalnızca ve ancak karşılaştırılan işlenenlerin ikili basamakları farklıysa işlenenin ikili bitini ayarlar.

0111 1111
1011 1001
^_________
1100 0110

Bit düzeyinde özel VEYA operatörü, çeşitli durumlarda yararlı olabilecek ilginç bir özelliğe sahiptir. Yani önce bir X değerinin bitsel özel VEYA işlemini başka bir Y değeri ile gerçekleştirirseniz ve daha sonra aynı işlemi bir önceki işlemin sonucu ve Y değeri üzerinde yaparsanız, orijinal X değerini tekrar alırsınız. aşağıdaki kod parçasında

R1 = X ^ Y;
R2 = R1 ^ Y;

R2'nin değeri, X'in değeriyle aynı olur. Bu nedenle, aynı değeri kullanan iki ardışık bit düzeyinde özel VEYA işlemi orijinal değeri üretir. Bu işlemin bu özelliği, mesajın karakterleri üzerinde özel bir VEYA işlemi kullanarak bir mesajı kodlamak ve kodunu çözmek için bir tamsayı değerinin bir anahtar görevi gördüğü basit bir şifreleme programı yazmak için kullanılabilir. İlkinde, düz metni şifreli metne kodlamak için özel bir VEYA işlemi, ikincisinde ise şifreli metni düz metne dönüştürmek için özel bir VEYA işlemi gerçekleştirilir. Tabii ki, böyle bir şifrelemenin pratik bir değeri yoktur, çünkü kolayca deşifre edilebilir. Bununla birlikte, aşağıdaki programda olduğu gibi, bit düzeyinde özel VEYA operatörlerini kullanmanın sonuçlarını göstermek için ilginç bir örnek olarak hizmet eder.

// Bit düzeyinde özel VEYA operatörünün kullanımını gösterin.

Sistemi kullanarak;
sınıf Kodla (
statik boşluk Ana () (
karakter ch1 = "H";
karakter ch2 = "i";
karakter ch3 = "!";
int anahtarı = 88;
Console.WriteLine ("Orijinal mesaj:" + ch1 + ch2 + ch3);
// Mesajı şifrele
ch1 = (char) (ch1 ^ tuşu);
ch2 = (char) (ch2 ^ tuşu);
ch3 = (char) (ch3 ^ tuşu);
Console.WriteLine ("Şifreli mesaj:" + ch1 + ch2 + ch3);
// Mesajın şifresini çöz.
ch1 = (char) (ch1 ^ tuşu);
ch2 = (char) (ch2 ^ tuşu);
ch3 = (char) (ch3 ^ tuşu);
Console.WriteLine ("Şifresi çözülmüş mesaj:" + ch1 + ch2 + ch3);
}
}

Orijinal gönderi: Merhaba!
Şifreli mesaj: Qly
Şifresi Çözülmüş Mesaj: Merhaba!

Gördüğünüz gibi, iki dizi bit düzeyinde özel VEYA işlemi gerçekleştirmek, şifresi çözülmüş bir mesajla sonuçlanır. (Aslında güvenilmez olduğundan, bu tür şifrelemenin pratik bir değeri olmadığını bir kez daha hatırlayın.)

Bitsel tekli operatör NOT (veya 1'in tümleyen operatörü), işlenenin tüm ikili bitlerinin durumunu tersine çevirir. Dolayısıyla, eğer bir A tamsayı değeri 1001 0110 bitlerinin bir kombinasyonuna sahipse, o zaman ~ A bitsel işlemin bir sonucu olarak, 0110 1001 bitlerinin bir kombinasyonuna sahip bir değer elde edilir.

Aşağıdaki program örneği, bir sayıyı ve 1'in tamamlayıcısını ikili kodda yazdırmak için bit düzeyinde NOT operatörünün kullanımını gösterir.

// Bit düzeyinde tekli NOT operatörünün kullanımını gösterin.
Sistemi kullanarak;
sınıf NotDemo (
statik boşluk Ana () (
sbyte b = -34;
for (int t = 128; t> 0; t = t / 2) (

}
Console.WriteLine();
// tüm bitleri ters çevir b = (sbyte) ~ b;
b = (sbyte) ~ b;
for (int t = 128; t> 0; t = t / 2) (
if ((b & t)! = 0) Console.Write ("1");
if ((b & t) == 0) Console.Write ("0");
}
}
}

Bu programın sonucu aşağıda gösterilmiştir.

1 1 0 1 1 1 1 0
0 0 1 0 0 0 0 1

Vardiya operatörleri

C#, bir tamsayı değeri oluşturan ikili basamakları belirli bir miktarda sola veya sağa kaydırma özelliğine sahiptir. Bu amaçla, C# aşağıdaki iki bit kaydırma operatörünü tanımlar.

<< Сдвиг влево
>> Sağa Kaydır

Bu operatörler için genel form aşağıdadır:

"sayı_bitleri" değeri
"sayı_bitleri" değeri

nerede sayı_bitleri belirtilen ikili basamak sayısıdır anlam.

Sola kaydırıldığında, belirtilen değerdeki tüm ikili basamaklar bir konum sola kaydırılır ve en az anlamlı bit sıfıra temizlenir. Sağa kaydırma, belirtilen değerdeki tüm ikili basamakları bir konum sağa kaydırır. İşaretsiz bir tamsayı değeri sağa kaydırılırsa, en anlamlı bit sıfırlanır. Ve işaretli bir tamsayı değeri sağa kaydırılırsa, işaret biti korunur. Negatif sayıları temsil etmek için bir tamsayının en anlamlı bitinin 1'e ayarlandığını hatırlayın. Dolayısıyla, kaydırılacak değer negatifse, sağa her kaydırmada sayının en anlamlı biti 1'e ayarlanır. Kaydırılan değer pozitifse, sağa yapılan her kaydırma ile sayının en önemli biti sıfırlanır.

Sola ve sağa kaydırırken, en dıştaki bitler kaybolur. Vardiya sırasında kaybolan bitleri kurtarmak imkansızdır, çünkü bu vardiyadaki vardiya durum döngüsel değildir.

Aşağıda, sola ve sağa kaydırmanın etkisini açıkça gösteren örnek bir program bulunmaktadır. Bu örnekte, ilk tamsayı değeri 1'e ayarlanmıştır. Bu, bu değerin en az anlamlı bitinin ayarlandığı anlamına gelir. Bu tamsayı değeri daha sonra art arda sekiz kez sola kaydırılır. Her kaydırmadan sonra, verilen değerin en az anlamlı sekiz biti çıktılanır. İşlem daha sonra tekrarlanır, ancak bu sefer 1 sekizinci bit konumuna ayarlanır ve esas olarak 128'lik bir tamsayı değeri ayarlanır, bu daha sonra art arda sekiz kez sağa kaydırılır.

// Vardiya operatörlerinin kullanımını gösterin.
Sistemi kullanarak;
sınıf ShiftDemo (
statik boşluk Ana () (
int değer = 1;
for (int ben = 0; ben< 8; i++) {
for (int t = 128; t> 0; t = t / 2) (
if ((val & t)! = 0) Console.Write ("1");
if ((val & t) == 0) Console.Write ("0");
}
Console.WriteLine();
değer = değer<< 1; // сдвиг влево
}
Console.WriteLine();
değer = 128;
for (int ben = 0; ben< 8; i++) {
for (int t = 128; t> 0; t = t / 2) (
if ((val & t)! = 0) Console.Write ("1");
if ((val & t) == 0) Console.Write ("0");
}
Console.WriteLine();
değer = değer >> 1; // sağa kaydır
}
}
}

Bu programın sonucu aşağıdaki gibidir.

0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 0
0 0 0 0 0 1 0 0
0 0 0 0 1 0 0 0
0 0 0 1 0 0 0 0
0 0 1 0 0 0 0 0
0 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1

İkili basamaklar, sayıların 2'nin kuvvetine göre temsiline karşılık gelir ve bu nedenle kaydırma operatörleri, tam sayıları 2 ile çarpmak veya bölmek için kullanılabilir. Örneğin, sağa kaydırma, tamsayı değerini ikiye katlar ve sola kaydırırken yarıya indirir. Tabii ki, tüm bunlar yalnızca bir yöne veya diğerine geçerken aşırı deşarjlar kaybolmazsa doğrudur. İlgili bir örnek aşağıda gösterilmiştir.

// 2 ile çarpma ve bölme için kaydırma operatörlerini uygulayın.
Sistemi kullanarak;
sınıf MultDiv (
statik boşluk Ana () (
int n;
n = 10;
Console.WriteLine ("n değişkeninin değeri:" + n);
// 2 ile çarp.
n = n<< 1;
"işlemler n = n * 2:" + n);
// 4 ile çarp.
n = n<< 2;
Console.WriteLine ("n değişkeninin değeri: sonra" +
"işlemler n = n * 4:" + n);
// 2'ye böl.
n = n >> 1;
Console.WriteLine ("n değişkeninin değeri: sonra" +
"işlemler n = n / 2:" + n);
// 4'e böl.
n = n >> 2;
Console.WriteLine ("n değişkeninin değeri: sonra" +
"işlemler n = n / 4:" + n);

Console.WriteLine();

// n değişkenini orijinal durumuna ayarlayın,
n = 10;
Console.WriteLine ("n değişkeninin değeri:" + n);
// 2 ile otuz kez çarpın.
n = n<< 30; // данные теряются
Console.WriteLine ("n sonra değişkenin değeri" +
"30 konum sola kaydır:" + n);
}
}

Bu programın çıktısı aşağıdadır.

n değişkeninin değeri: 10
n değişkeninin değeri: işleminden sonra n = n * 2: 20
n değişkeninin değeri: işleminden sonra n = n * 4: 80
n değişkeninin değeri: işlemin ardından n = n / 2: 40
n değişkeninin değeri: işleminden sonra n = n / 4: 10
n değişkeninin değeri: 10
30 konum sola kaydırıldıktan sonraki n değeri: -2147483648

Yukarıdaki sonucun son satırına dikkat edin. 10 tamsayı değeri art arda otuz kez sola kaydırıldığında, ikili basamaklar int'nin dışına kaydırıldığından bilgi kaybolur. Bu durumda, işaret olarak kullanılan en önemli bitteki kaymanın bir sonucu olarak, 1 göründüğü ve bu nedenle, bu sayısal değerin, negatif olduğu ortaya çıkan tamamen "" kullanılamaz "değer elde edilir ve bu nedenle, bu sayısal değer olmalıdır. 2 ile çarpma veya bölme için shift operatörlerini kullanırken çok dikkatli olmalısınız (imzalı ve imzasız veri türleri hakkında daha fazla bilgi için Bölüm 3'e bakın.)

Bitsel Bileşik Atama Operatörleri

Tüm ikili bitsel operatörler, bileşik atamalarda kullanılabilir. Örneğin, aşağıdaki iki ifadede, x'in orijinal değeri ve 127 sayısal değeri üzerinde bir dışlamalı VEYA işleminin sonucu x'e atanır.

x = x ^ 127;
x^ = 127;