Daha karmaşık mantık kapıları. Özel kapı veya Xor örnekleri

Bu yazımızda bazı bit işlemlerinden bahsedeceğiz. Başlıcalarını ele alalım: XOR (özel VEYA), VE (VE), DEĞİL (DEĞİL) ve VEYA (VEYA).

Bildiğiniz gibi, minimum bilgi ölçüm birimi biraz 2 değerden birini saklayan: 0 ( Yanlış, yanlış) veya 1 ( NS, NS). Bu nedenle, bir bit hücresi aynı anda sadece iki olası durumdan birinde olabilir.

Bitleri işlemek için belirli işlemler kullanılır - mantıksal veya boole... Sıfır veya bir olmasına bakılmaksızın herhangi bir bit'e uygulanabilirler. Pekala, üç temel mantıksal işlemi kullanma örneklerine bakalım.

Mantıksal VE (ve) işlemi

VE& ile gösterilir.

AND operatörü 2 bit ile gerçekleştirilir, örneğin a ve b alın. a ve b 1 ise VE sonucu 1'dir. Aksi takdirde sonuç 0'dır. Örneğin, bir sayının çift olup olmadığını öğrenmek için VE kullanabilirsiniz.

AND işleminin doğruluk tablosuna bakın:

Mantıksal VEYA işlem

işaretiyle belirtilir | ...

Şebeke VEYA ayrıca 2 bit (a ve b) ile yapılır. a ve b 0 ise sonuç 0, değilse 1'dir. Doğruluk tablosuna bakın.

Mantıksal XOR (özel VEYA)

XOR operatörü ^ ile gösterilir.

XOR 2 bit (a ve b) ile yürütülür. XOR işleminin sonucu ( özel veya) b veya a bitlerinden biri 1 olduğunda 1'dir. Aksi takdirde, XOR operatörünün sonucu 0'dır.

XOR (özel VEYA) için mantıksal işlemin doğruluk tablosu şöyle görünür:

XOR (exclusive OR) kullanarak aynı veri türündeki 2 değişkenin değerlerini geçici bir değişken kullanmadan takas edebilirsiniz. Ayrıca, XOR kullanarak metni şifreleyebilirsiniz, örneğin:

String msg = "Bu bir mesajdır"; char mesajı = msg.toCharArray(); Dize anahtarı = ". *)"; String şifreliString = new String(); for (int ben = 0; ben< message.length; i++){ encryptedString += message[i]^key.toCharArray(); }

XOR'un en güvenilir şifreleme yönteminden uzak olduğuna katılıyorum, ancak bu, herhangi bir şifreleme algoritmasının parçası yapılamayacağı anlamına gelmez.

Mantıksal DEĞİL işlemi

Bu bit düzeyinde olumsuzlamadır, bu nedenle bir bit ile gerçekleştirilir ve ~ ile gösterilir.

Sonuç, bitin durumuna bağlıdır. Sıfır durumundaysa, işlemin sonucu birdir ve bunun tersi de geçerlidir. Her şey son derece basit.

Bu 4 mantıksal işlem her şeyden önce hatırlanmalıdır, çünkü onların yardımıyla hemen hemen her olası sonucu elde edebilirsiniz. gibi işlemler de vardır.<< (побитовый сдвиг влево) и >> (bit düzeyinde sağa kaydırma).

Assembler'daki XOR komutu, iki işlenenin tüm bitleri arasında özel bir VEYA işlemi gerçekleştirir. XOR işleminin sonucu ilk işlenene yazılır. Sözdizimi:

XOR ALICI, KAYNAK

XOR komutu her zaman CF ve OF'yi temizler ve ayrıca (sonuca bağlı olarak) SF, ZF ve PF bayraklarını değiştirir. AF bayrağının değeri herhangi bir şey olabilir - işlemin sonucuna bağlı değildir.

ALICI aşağıdakilerden biri olabilir:

  • Bellek alanı (MEM)

KAYNAK aşağıdakilerden biri olabilir:

  • Bellek alanı (MEM)
  • Genel Amaçlı Kayıt (REG)
  • Anında Değer - Sabit (IMM)

Yukarıda açıklanan sınırlamalar dikkate alındığında, SINTER-SOURCE kombinasyonları aşağıdaki gibi olabilir:

REG, MEM MEM, REG REG, REG MEM, IMM REG, IMM

Özel VEYA işlemi

Özel bir VEYA işlemi gerçekleştirirken, karşılaştırılan bitler farklıysa (eşit değilse) sonuç 1 olacaktır. Karşılaştırılan bitler aynı değere sahipse, sonuç 0 olacaktır.

Bu nedenle, bu işleme özel denir. Aynı bitleri karşılaştırmanın dışında tutar ve eşit olmayan bitlerle bir işlem gerçekleştirir.

Ancak, herhangi bir eşit olmayan bit çifti 0 ve 1 olduğundan, mantıksal VEYA işlemi 1 ile sonuçlanacaktır.

Özel VEYA Doğruluk Tablosu

XOR doğruluk tablosu aşağıda gösterilmiştir:

0 XOR 0 = 0 0 XOR 1 = 1 1 XOR 0 = 1 1 XOR 1 = 0

XOR işleminin özellikleri

XOR işlemi tersine çevrilebilir. Aynı işlenenle iki kez çalıştırılırsa, sonuç değeri ters çevrilir. Yani bu işlemi bitler arasında iki kez yaparsanız x ve Y, sonra sonuçta orijinal bit değerini elde ederiz NS.

0 XOR 0 = 0 XOR 0 = 0 0 XOR 1 = 1 XOR 1 = 0 1 XOR 0 = 1 XOR 0 = 1 1 XOR 1 = 0 XOR 1 = 1

Bu özellik, örneğin, en basit veri şifreleme için kullanılabilir (başka bir zaman bu konuda daha fazlası).

XOR işleminden sonra parite kontrolü

XOR komutu 8-, 16- ve 32-bit işlemlerle çalışır.

Bazen, bir işlem gerçekleştirdikten sonra, içinde kaç tane tek bitin (çift veya tek) bulunduğunu bulmak için eşlik bayrağını PF kontrol etmek için bir ihtiyaç vardır. düşük bayt sonuç (bu yalnızca bir XOR işlemi gerçekleştirirken değil, aynı zamanda diğer aritmetik ve mantıksal işlemler gerçekleştirirken de gereklidir).

Eşlik bayrağı ayarlanmışsa, sonuç çift sayıda bir bit olur. Aksi takdirde bayrak silinecektir.

Ayrıca sonucun değerini değiştirmeden herhangi bir sayının düzgünlüğünü kontrol edebilirsiniz. Bunu yapmak için XOR komutunu sıfır değeriyle çalıştırmanız gerekir. Yani, ALICI'da kontrol edilmiş bir sayı olmalı ve KAYNAK'ta sıfır olmalıdır. Ve sonra parite bayrağını kontrol etmeniz gerekiyor. Örnek:

AL, 10110101b; AL'ye tekli bir sayı koyun; bir bit sayısı (5) XOR AL, 0; Bu durumda parite bayrağı PF değildir; (PO) MOV AL, 10110111b'yi ayarlayın; AL'ye bir sayı koyun bir çift ile; bir bit sayısı (6) XOR AL, 0; Bu durumda, eşlik bayrağı PF; ayarlanacaktır (PE)

Hata ayıklayıcılarda, PE (Çift Parite) kısaltması genellikle sonuçtaki bir çift sayıda birimi belirtmek için ve PO (Tek Parite) tek bir sayıyı belirtmek için kullanılır.

16-bit kelimelerde parite

Daha önce de belirtildiği gibi, parite bayrağı, sonucun düşük baytında bulunanların sayısına bağlı olarak ayarlanır. 16 bitlik bir işlenenin paritesini kontrol etmek için, bu sayının yüksek ve düşük baytları arasında bir XOR komutu gerçekleştirmelisiniz:

MOV AX, 64C1h; 0110 0100 1100 0001 - 6 bir bit XOR AH, AL; Parite bayrağı ayarlanacak

Bu basit yolla, 16 bitlik işlenen iki bayta bölünür (8 bitlik 2 grup) ve XOR komutu yürütüldüğünde, iki 8 bitlik işlenenin karşılık gelen bitlerindekiler dikkate alınmayacaktır. . Çünkü sonucun karşılık gelen biti sıfırdır.

XOR komutu, sonuçtan iki 8 bitlik işlenenden çakışan 1 biti kaldırır ve sonuca çakışmayan 1 bit ekler. Yani aldığımız 8 bitlik sayının paritesi orijinal 16 bitlik sayının paritesiyle aynı olacaktır.

0110 0100 1100 0001 - orijinal 16 bitlik sayı 0 XOR 1 = 1 1 XOR 1 = 0 1 XOR 0 = 1 0 XOR 0 = 0 0 XOR 0 = 0 1 XOR 0 = 1 0 XOR 0 = 0 0 XOR 1 = 1

Sonuç olarak 4 adet yani PF bayrağı ayarlanacaktır.

32 bit çift sözcüklerde eşlik

Peki ya 32 bitlik bir sayıdaki pariteyi belirlemeniz gerekirse?

Daha sonra sayı dört bayta bölünür ve bu baytlarla dönüşümlü olarak özel bir VEYA işlemi gerçekleştirilir.

Örneğin, 32 bit sayıyı böldük B dört bayt ile B0, B1, B2, B3, nerede B0 en az anlamlı bayttır.

Ardından, B sayısının paritesini belirlemek için aşağıdaki formülü kullanmamız gerekecek:

B0 XOR B1 XOR B2 XOR B3

Ancak montajcıda böyle bir girişe izin verilmez. O yüzden biraz düşünmelisin.

Ve son olarak, anımsatıcıların kökeni hakkında XOR... İngilizcede e kelimesi var x resepsiyon bir istisnadır. Bu kelimenin kısaltması harftir. NS(böyle oldu). Bunu muhtemelen reklamlarda veya üreticilerinin münhasır olduğunu iddia ettiği (veya iddia ettiklerini düşündükleri) ürünlerin adlarında görmüşsünüzdür. Örneğin, Lada XRAY, Sony XPeria, vb. Yani XOR iki kelimelik bir kısaltmadır - e x resepsiyon VEYA- özel veya.

Pratikte, en sık olarak iki girişli özel VEYA öğeleri kullanılır. İncirde. 1, tersine çevrilmemiş bir elemanın geleneksel bir grafik gösterimini ve durum tablosunu gösterir. Basit bir ifadeyle, bu elemanın özü aşağıdaki gibidir, çıkış sinyali yalnızca girişlerdeki mantık seviyeleri aynı olmadığında görünür.

Ön kenarın seçim şeması ve darbenin kesilmesi

Bu devrede, darbeleri geciktirmek için üç XOR kapısı kullanılır. DD1.4 - özetleme. Çıkış darbeleri sabit kenarlara ve kenarlara sahiptir. Her çıkış darbesinin süresi, üç elemanın her birinin anahtarlama gecikme süresinin üç katına eşittir. Çıkış darbelerinin kenarları arasındaki zaman aralığı, giriş darbesinin süresine eşittir. Ayrıca, bu cihaz giriş sinyalinin frekansını iki katına çıkarır.

"Exclusive OR" adlı ilginç bir özellik daha var. Girişlerden birine sabit bir "0" uygulanırsa, elemanın çıkışındaki sinyal giriş sinyalini tekrar eder ve "0" sabiti "1" olarak değiştirilirse, çıkış sinyali zaten giriş sinyalinin tersi olsun.

Bazen ayrı standart mantıksal öğelerden özel bir VEYA öğesi elde etmek gerekli hale gelir. Bir örnek, dört 2-VE-NOT öğesi üzerinde uygulanan "özel VEYA" öğe şemasıdır. Şekil 3, dört durumda özel bir VEYA gösterir. Kullanılan 2-VE-DEĞİL mantık kapılarının her biri üzerindeki olası tüm mantık seviyeleri burada gösterilmektedir.

Bu tür unsurlar şemaya dahil edilmiştir. Bu devrede, "Özel VEYA" elemanı, K561LA7 mikro devresinin bir gövdesinde bulunan dört 2-VE-NOT elemanı üzerinde yapılır.

Fark frekansına sahip ayrık bir sinyal üreteci

Sürücü devresi Şekil 4'te gösterilmektedir. Burada, özel VEYA kapısı ayrıca dört 2-VE-DEĞİL kapısı üzerinde uygulanmaktadır.

Şekillendiricinin 1 ve 2 girişlerinde, tekrarlama oranlarında farklılık gösteren dikdörtgen darbeler meydana gelir (bkz. Grafik 1 ve 2). DD1.1-DDI.4 mantıksal öğelerindeki düğüm bu sinyalleri çoğaltır. DD1.4 elemanından gelen çıkış darbe sinyali (grafik 3), onu giriş sinyallerinin frekans farkına eşit bir frekansla üçgen bir sinyale (grafik 4) ve OA'ya dönüştüren R3, C1 entegre devresine beslenir. DA1, alınan sinyali bir kıvrıma dönüştürür (bkz. grafik 5). Direnç R1, çıkış sinyalinin pozitif ve negatif yarım dalgalarının süresini ayarlar. Çok ilginç bir şema. Radyo tasarımcısının düşünmesi gereken bir şey var. Örneğin, üçüncü grafikte gösterilen sinyal bir sinüs dalgası PWM sinyalidir.
Tabii ki, XOR öğelerinin kullanım alanı çok daha geniştir. Ben buraya radyo amatörleri için daha ilgi çekici bir fikir getirdim.

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 yüksek seviyeli programlama dili olarak kalmasına yol açmıştır. Bitsel işlemlere genel bir bakış olmadan elbette dil öğrenimi eksik kalacaktır.

Bitsel işlemler, adından da anlaşılacağı gibi, doğrudan bitlerle işlem yapmanızı sağlar. Bitsel işlemlerin kullanımına ilişkin çok sayıda örnek, ö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

Bir başlangıç ​​için, AND, OR, özel OR ve NOT mantıksal işlemlerinin doğruluk tabloları kullanılarak tanımlanabileceğini hatırlatmama izin verin.

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: Bir sayının ek kodunu bulmak için onu tersine çevirmeniz ve ona bir tane eklemeniz gerekir.

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.

Bazen 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

Bit düzeyinde 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 little-endian veya orta-endian), ikili sayılar soldan sağa, en anlamlı bitten en az anlamlıya doğru temsil edilir. 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 tamsayı ikiye bölmeye eşdeğerdir ve sola kaydırma 2 ile çarpma işlemidir. Bunun nedeni, C'nin tanımlanmış bir kayan nokta gösterimine sahip olmamasıdır. Ancak, bir kayan noktayı bir int'ye taşıyabilir, ardından kaydırıp geri döndürebilirsiniz.

Ş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. Aslında, 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 ("(işaretsiz) sa =% u, sa >> 2 =% u \ n", sa, sa >> 2); printf ("sa =% d, ((işaretsiz) sa) >> 2 = % d", sa, ((işaretsiz) sa) >> 2);

Bu durumda, 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. Aritmetik operatörler gibi karmaşık bir atamanın parçası olabilirler.

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ıra eşit olduğu bir sayı ile çarparız:

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

Fonksiyon 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ıyla 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 sıklıkla 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ığı.

Çoğu zaman, tek katmanlı algılayıcıların problem çözmedeki sınırlı yeteneklerini göstermek için, sözde problemi dikkate almaya başvururlar. XOR - özel VEYA.

Sorunun özü aşağıdaki gibidir. Size mantıksal bir XOR işlevi verilir - özel VEYA. Her biri sıfır veya bir olabilen iki bağımsız değişkenin bir işlevidir. Argümanlardan biri bir olduğunda, ancak ikisi birden olmadığında bir değer alır, aksi takdirde. Problem, aşağıdaki şekilde gösterildiği gibi, iki girişli tek katmanlı, tek nöronlu bir sistemle gösterilebilir.

Bir girdiyi ve diğerini içinden atayalım, o zaman tüm olası kombinasyonları düzlemde dört noktadan oluşacaktır. Aşağıdaki tablo, sıfır çıkış vermesi gereken giriş kombinasyonlarının ve ile etiketlendiği girişler ve çıkışlar arasındaki gerekli bağlantıyı gösterir ve ve ile tek çıkış.

Puan Anlam Anlam Istenilen çıktı
0 0 0
1 0 1
0 1 1
1 1 0

İki girişi olan bir nöron, rastgele bir düz çizgi şeklinde bir karar yüzeyi oluşturabilir. Ağın yukarıdaki tabloda belirtilen XOR işlevini uygulayabilmesi için, düz çizgiyi, noktalar düz çizginin bir tarafında ve noktalar diğer tarafında olacak şekilde konumlandırmanız gerekir. Aşağıdaki şekilde böyle düz bir çizgi çizmeye çalıştıktan sonra bunun imkansız olduğuna ikna olduk. Bu, ağırlıklara ve eşiklere atanan değerler ne olursa olsun, tek katmanlı bir sinir ağının bir XOR işlevini temsil etmek için gereken girdi-çıktı ilişkisini yeniden üretemediği anlamına gelir.

Bununla birlikte, XOR işlevi, iki katmanlı bir ağ tarafından ve birçok yönden kolayca oluşturulabilir. Bu yöntemlerden birini ele alalım. Başka bir gizli nöron katmanı ekleyerek şekildeki ağı modernize edelim:

Bu ağın olduğu gibi verildiğini unutmayın, yani. zaten eğitim almış olduğu düşünülebilir. Okların üzerindeki sayılar sinaptik ağırlıkları gösterir. Aktivasyon fonksiyonu olarak, aşağıdaki grafiğe sahip olan, eşik değeri olan tek bir atlama fonksiyonu kullanıyoruz:

Daha sonra böyle bir sinir ağının çalışmasının sonucu aşağıdaki tablo şeklinde sunulabilir:

Puan Anlam Anlam Istenilen çıktı
0 0 0 0 0 0
1 0 1 1 0 1
0 1 1 0 1 1
1 1 0 0 0 0

Birinci katmanın iki nöronunun her biri, keyfi bir düz çizgi şeklinde bir karar yüzeyi oluşturur (düzlemi iki yarı düzleme böler) ve çıktı katmanının nöronu, bu iki çözümü birleştirerek bir karar yüzeyi oluşturur. birinci katmanın nöronlarının paralel düz çizgilerinden oluşan bir şerit şekli:

Bu makalede XOR sorununu çözmek için kullanılan sinir ağı ilkeldir ve çok katmanlı ağlardan tam olarak faydalanmaz. Açıkçası, çok katmanlı sinir ağları, yalnızca doğrusal olmama durumunda, tek katmanlı olanlardan daha fazla temsil gücüne sahiptir. Ve bu ağda bir eşik lineer aktivasyon fonksiyonu uygulanır. Böyle bir ağ, örneğin hata geri yayılım algoritması kullanılarak eğitilemez.

gastroguru 2017