Bitsel operatörler nedir?


130

Ben sadece eğlenmek için kod yazan ve akademik ya da profesyonel bir ortamda onu gerçekten derinlemesine araştırmamış biriyim, bu yüzden bu bitsel operatörler gibi şeyler benden gerçekten kaçıyor.

Görünüşe göre bitsel işlemleri destekleyen JavaScript hakkında bir makale okuyordum. Bu operasyondan bazı yerlerde bahsedildiğini görmeye devam ediyorum ve tam olarak ne olduğunu anlamaya çalıştım, ama hiç anlamıyorum. Öyleyse bunlar nedir? Açık örnekler harika olur! : D

Sadece birkaç soru daha - bitsel işlemlerin bazı pratik uygulamaları nelerdir? Onları ne zaman kullanabilirsin?


2
Daha fazla soru için, yeni bir SO sorusu eklemek ve buna referans vermek isteyebilirsiniz. Muhtemelen bu şekilde daha iyi cevaplar alacaksınız.
Greg Hewgill

Yanıtlar:


187

Kimse bunların neden yararlı olduğu konusunu açmadığına göre:

Bayraklarla çalışırken bitsel işlemleri çok kullanıyorum. Örneğin, bir işleme bir dizi bayrak geçirmek istiyorsanız (örneğin, File.Open()Okuma modu ve Yazma modu etkinken), bunları tek bir değer olarak iletebilirsiniz. Bu, her olası bayrağa bir bit kümesinde (bayt, kısa, int veya uzun) kendi bitini atayarak gerçekleştirilir. Örneğin:

 Read: 00000001
Write: 00000010

Bu nedenle, okuma VE yazma geçmek istiyorsanız, (READ | WRITE) geçersiniz ve bu da ikisini

00000011

Daha sonra diğer tarafta şu şekilde şifresi çözülebilir:

if ((flag & Read) != 0) { //...

hangi kontroller

00000011 &
00000001

hangi döner

00000001

0 değildir, bu nedenle bayrak READ'i belirtir.

Çeşitli bitleri değiştirmek için XOR'u kullanabilirsiniz. Yönlü girişleri (Yukarı, Aşağı, Sol, Sağ) belirtmek için bir bayrak kullanırken bunu kullandım. Örneğin, bir hareketli grafik yatay olarak hareket ediyorsa ve ben onun geri dönmesini istiyorum:

     Up: 00000001
   Down: 00000010
   Left: 00000100
  Right: 00001000
Current: 00000100

Sadece mevcut değeri (LEFT | RIGHT) ile XOR, bu durumda SOL'u kapatır ve SAĞı açar.

Bit Kaydırma birkaç durumda faydalıdır.

x << y

aynıdır

x * 2 y

hızlı bir şekilde ikinin kuvveti ile çarpmanız gerekiyorsa, ancak 1 biti en üst bite kaydırmaya dikkat edin - bu, işaretsiz değilse sayıyı negatif yapar. Farklı boyutlardaki verilerle uğraşırken de kullanışlıdır. Örneğin, dört bayttan bir tamsayı okumak:

int val = (A << 24) | (B << 16) | (C << 8) | D;

A'nın en önemli bayt ve en az D olduğunu varsayarsak. Şöyle biterdi:

A = 01000000
B = 00000101
C = 00101011
D = 11100011
val = 01000000 00000101 00101011 11100011

Renkler genellikle şu şekilde depolanır (en önemli bayt yok sayılır veya Alfa olarak kullanılır):

A = 255 = 11111111
R = 21 = 00010101
G = 255 = 11111111
B = 0 = 00000000
Color = 11111111 00010101 11111111 00000000

Değerleri tekrar bulmak için, bitleri en alta gelene kadar sağa kaydırın, ardından kalan yüksek dereceli bitleri maskeleyin:

Int Alpha = Color >> 24
Int Red = Color >> 16 & 0xFF
Int Green = Color >> 8 & 0xFF
Int Blue = Color & 0xFF

0xFFile aynıdır 11111111. Yani aslında Red için şunu yaparsınız:

Color >> 16 = (filled in 00000000 00000000)11111111 00010101  (removed 11111111 00000000)
00000000 00000000 11111111 00010101 &
00000000 00000000 00000000 11111111 =
00000000 00000000 00000000 00010101 (The original value)

x << n, yani n 2 ^ değer biçiminde olmalıdır?
Ahmed C

28

Diğer yanıtlar olarak listelenen tek bitlik doğruluk tablolarının aynı anda yalnızca bir veya iki giriş biti üzerinde çalıştığını belirtmek gerekir. Tam sayı kullandığınızda ne olur, örneğin:

int x = 5 & 6;

Cevap, her bir girişin ikili genişlemesinde yatmaktadır:

  5 = 0 0 0 0 0 1 0 1
& 6 = 0 0 0 0 0 1 1 0
---------------------
      0 0 0 0 0 1 0 0

Her sütundaki her bit çifti, alt satırda karşılık gelen çıktı bitini vermek için "VE" işlevi üzerinden çalıştırılır. Yani yukarıdaki ifadenin cevabı 4'tür. CPU (bu örnekte) paralel olarak her sütun için bir tane olmak üzere 8 ayrı "VE" işlemi yapmıştır.

Bundan bahsediyorum çünkü hala bu "AHA!" Bunu yıllar önce öğrendiğim an.


Vay canına, bu artık çok daha mantıklı. Göründüğünden çok daha karmaşık geliyordu. Teşekkürler. Ben iyi olanlar sürü gibi doğru cevabı olarak seçmek ve ben upvote yüzden .. teşekkürler edemez hangi emin değilim
tıklayın

27

Bitsel operatörler, her seferinde bir bit üzerinde çalışan operatörlerdir.

AND, yalnızca her iki girişi de 1 ise 1'dir.

Girişlerinden biri veya daha fazlası 1 ise OR 1'dir.

XOR, yalnızca girişlerinden biri 1 ise 1'dir.

NOT, yalnızca girişi 0 ise 1'dir.

Bunlar en iyi doğruluk tabloları olarak tanımlanabilir. Giriş olasılıkları üstte ve solda, sonuçta ortaya çıkan bit, iki girişin kesişme noktasında gösterilen dört değerden biridir (NOT durumunda sadece bir girişe sahip olduğu için iki) değer.

AND|0 1      OR|0 1
---+----    ---+----
  0|0 0       0|0 1
  1|0 1       1|1 1

XOR|0 1     NOT|0 1
---+----    ---+---
  0|0 1        |1 0
  1|1 0

Bir örnek, bir tamsayının yalnızca 4 bitinin altını istiyorsanız, siz VE 15 (ikili 1111) ile:

    203: 1100 1011
AND  15: 0000 1111
------------------
 IS  11: 0000 1011

16

Bunlar, tümü JavaScript'te desteklenen bitsel operatörlerdir:

  • op1 & op2- ANDOperatör iki biti karşılaştırır ve her iki bit de 1 ise 1 sonucunu oluşturur; aksi takdirde 0 döndürür.

  • op1 | op2- OROperatör iki biti karşılaştırır ve bitler tamamlayıcıysa 1 sonucunu üretir; aksi takdirde 0 döndürür.

  • op1 ^ op2- EXCLUSIVE-OROperatör iki biti karşılaştırır ve bitlerden biri 1 ise 1 döndürür ve her iki bit de 0 veya 1 ise 0 verir.

  • ~op1- COMPLEMENTOperatör, işlenenin tüm bitlerini ters çevirmek için kullanılır.

  • op1 << op2- SHIFT LEFTOperatör bitleri sola hareket ettirir, en soldaki biti atar ve en sağdaki bit 0 değerini atar. Sola yapılan her hareket op1'i 2 ile etkili bir şekilde çarpar.

  • op1 >> op2 - SHIFT RIGHT Operatör bitleri sağa hareket ettirir, en sağdaki biti atar ve en soldaki bit 0 değerini atar. Sağa yapılan her hareket op1'i etkili bir şekilde ikiye böler. En soldaki işaret biti korunur.

  • op1 >>> op2- SHIFT RIGHT- ZERO FILLoperatörü bitleri sağa hareket ettirir, en sağdaki biti atar ve en soldaki bit 0 değerini atar. Sağa yapılan her hareket op1'i etkili bir şekilde ikiye böler. En soldaki işaret biti atılır.


"eğer bitler tamamlayıcıysa" - waht?
Andrey Tyukin

@AndreyTyukin, biri 1 diğeri 0 ise iki bit tamamlayıcıdır.
Jeff Hillman

@JeffHillman Yorumdaki açıklamanıza göre, 1 ve 1 "tamamlayıcı" değildir. Öyleyse bana neden 1 | 1verip 1vermediği 0ve |o zaman nasıl farklı olacağı açık değil ^. Birkaç gün önce bu S / C'yi yinelenen hedef olarak kullanmak zorunda kaldım ve 10 yıl sonra birinin bu tür sorular için daha net bir kanonik kopyaya sahip olmasını diledim.
Andrey Tyukin

4

Biraz daha parçalamak gerekirse, söz konusu değerin ikili temsiliyle çok ilgisi var.

Örneğin (ondalık olarak):
x = 8
y = 1

çıkacaktı (ikili olarak):
x = 1000
y = 0001

Oradan, 've' veya 'veya' gibi hesaplama işlemleri yapabilirsiniz; bu durumda:
x | y =
1000 
0001 |
------
1001

veya ... ondalık olarak 9

Bu yardımcı olur umarım.


|OR operasyonları mı?
Si8

Bazı nedenlerden dolayı bu bana en mantıklı geldi. Yine de x | y = 1000 0001 |bölümden emin değilim
samayo

4

"Bitsel" teriminden bahsedildiğinde, bazen bunun "mantıksal" bir operatör olmadığını açıklığa kavuşturmaktadır.

Örneğin JavaScript'te bitsel operatörler, işlenenlerini 32 bitlik bir dizi (sıfırlar ve birler) olarak ele alır ; bu arada, mantıksal operatörler genellikle Boolean (mantıksal) değerlerle kullanılır, ancak Boole olmayan türlerle de çalışabilir.

Örneğin ifade1 && ifade2'yi ele alalım.

False değerine dönüştürülebilirse ifade1'i döndürür; aksi takdirde ifade2 döndürür. Bu nedenle, Boolean değerleriyle kullanıldığında, && her iki işlenen de doğruysa true; aksi takdirde false döndürür.

a = "Cat" && "Dog"     // t && t returns Dog
a = 2 && 4     // t && t returns 4

Diğerlerinin de belirttiği gibi, 2 & 4 bitsel AND'dir, bu yüzden 0 döndürür.

Aşağıdakileri test.html veya başka bir şey için kopyalayıp test edebilirsiniz:

<html>
<body>
<script>
    alert("\"Cat\" && \"Dog\" = " + ("Cat" && "Dog") + "\n"
        + "2 && 4 = " + (2 && 4) + "\n"
        + "2 & 4 = " + (2 & 4));
</script>

3

Dijital bilgisayar programlamasında, bitsel bir işlem, kendi bitlerinin seviyesinde bir veya daha fazla bit deseninde veya ikili sayılarda çalışır. Doğrudan işlemci tarafından desteklenen hızlı, ilkel bir eylemdir ve karşılaştırmalar ve hesaplamalar için değerleri değiştirmek için kullanılır.

operasyonlar :

  • bitsel AND

  • bitsel VEYA

  • bitsel DEĞİL

  • bit tabanlı ÖZELVEYA

  • vb

Liste öğesi

    AND|0 1        OR|0 1 
    ---+----      ---+---- 
      0|0 0         0|0 1 
      1|0 1         1|1 1 

   XOR|0 1        NOT|0 1 
   ---+----       ---+--- 
     0|0 1           |1 0 
     1|1 0

Örneğin.

    203: 1100 1011
AND  15: 0000 1111
------------------
  =  11: 0000 1011

Bitsel operatörün kullanımı

  • Sola kaydırma ve sağa kaydırma operatörleri, sırasıyla x * 2 y ile çarpma ve bölmeye eşdeğerdir .

Örneğin.

int main()
{
     int x = 19;
     printf ("x << 1 = %d\n" , x <<1);
     printf ("x >> 1 = %d\n", x >>1);
     return 0;
}
// Output: 38 9
  • & Operatörü, bir sayının tek mi çift mi olduğunu hızlı bir şekilde kontrol etmek için kullanılabilir

Örneğin.

int main()
{
    int x = 19;
    (x & 1)? printf("Odd"): printf("Even");
    return 0;
 }
// Output: Odd
  • Olmadan x ve y Hızlı bul asgari if elsedeyimi

Örneğin.

int min(int x, int y)
{
    return y ^ ((x ^ y) & - (x < y))
}
  • Ondalıktan ikiliye dönüştürme

Örneğin.

#include <stdio.h>
int main ()
{
    int n , c , k ;
    printf("Enter an integer in decimal number system\n " ) ;
    scanf( "%d" , & n );
    printf("%d in binary number
    system is: \n " , n ) ;
    for ( c = 31; c >= 0 ; c -- )
    {
         k = n >> c ;
         if ( k & 1 )
              printf("1" ) ;
         else
              printf("0" ) ;
      }
      printf(" \n " );
      return 0 ;
}
  • XOR geçit şifrelemesi, programcı tarafından uygunluğu ve yeniden kullanımı nedeniyle popüler bir tekniktir.
  • bitwise XOR operatörü, teknik görüşme açısından en kullanışlı operatördür.

bitsel kaydırma yalnızca + ve sayısıyla çalışır

Ayrıca bitsel mantığın geniş bir kullanım alanı vardır.


"complixblity and reare ..."?
Jonathan Çapraz

The left-shift and right-shift operators are equivalent to multiplication and division by x * 2y respectively.Doğru! muyiy.cn/question/program/102.html
xgqfrms


1

Bu şekilde düşünmek yardımcı olabilir. AND (&) şu şekilde çalışır:

Temelde bu sayıların her ikisinin de bir olduğunu söylüyor, yani iki sayı 5 ve 3 varsa, bunlar ikiliye dönüştürülecek ve bilgisayar düşünecek

         5: 00000101
         3: 00000011

ikisi de bir: 00000001 0 yanlış, 1 doğru

Yani 5 ve 3'ün AND'si birdir. OR (|) operatörü aynı şeyi yapar, ancak sayılardan yalnızca birinin 1 çıktı için bir olması gerekir, ikisi birden değil.


-5

JavaScript'in bitsel operatörlerinin ne kadar yavaş olduğunu duymaya devam ettim. En son blog yazım için bazı testler yaptım ve birkaç testte aritmetik alternatiften% 40 ila% 80 daha hızlı olduklarını öğrendim. Belki eskiden yavaşlardı. Modern tarayıcılarda onları seviyorum.

Kodumda bundan dolayı daha hızlı ve daha kolay okunacak bir durum var. Daha fazlası için gözlerimi açık tutacağım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.