Bit kaydırma operatörleri tam olarak isimlerinin ne anlama geldiğini yaparlar. Bitleri kaydırıyorlar. Farklı vardiya operatörlerine kısa (veya çok kısa olmayan) bir giriş.
Operatörler
>>
aritmetik (veya imzalı) sağ kaydırma operatörüdür.
>>>
mantıksal (veya imzasız) sağ kaydırma operatörüdür.
<<
sola kaydırma operatörüdür ve hem mantıksal hem de aritmetik kaymaların ihtiyaçlarını karşılar.
Bu operatörlerin tüm tamsayı değerlerine uygulanabilir ( int
, long
muhtemelen short
ve byte
ya char
). Bazı dillerde, vardiya operatörlerini int
otomatik olarak daha küçük herhangi bir veri tipine uygulamak, işleneni bir olarak yeniden boyutlandırır int
.
Bunun <<<
bir operatör olmadığını unutmayın , çünkü gereksiz olur.
Ayrıca C ve C ++ 'nın sağ kaydırma operatörleri arasında ayrım yapmadığını unutmayın . Yalnızca >>
operatörü sağlarlar ve sağa kayma davranışı, imzalı türler için tanımlanan bir uygulamadır. Yanıtın geri kalanı C # / Java işleçlerini kullanır.
( >>
İmzalı türlerde GCC ve Clang / LLVM dahil olmak üzere tüm ana C ve C ++ uygulamalarında aritmetiktir. Bazı kodlar bunu kabul eder, ancak standart garantili bir şey değildir. Yine de tanımlanmamıştır ; standart bunu tanımlamak için uygulamalara ihtiyaç duyar Öyle ya da böyle. Ancak negatif işaretli sayının sol kaymalar olduğu (taşma tamsayı imzalanmış) tanımsız davranış. Eğer aritmetik sağa kaydırma gerek Yani sürece, bunu yapmak için iyi bir fikir genellikle var senin bit değiştirme imzasız türleri ile.)
Sola kaydırma (<<)
Tamsayılar bellekte bir dizi bit olarak saklanır. Örneğin, 32 bit olarak depolanan 6 sayısı int
şöyle olur:
00000000 00000000 00000000 00000110
Bu bit desenini sola bir konuma ( 6 << 1
) kaydırmak, 12 rakamıyla sonuçlanır:
00000000 00000000 00000000 00001100
Gördüğünüz gibi, rakamlar bir konum sola kaymıştır ve sağdaki son rakam sıfır ile doldurulmuştur. Ayrıca sol kaydırma 2. So yetkileri ile çarpma eşdeğerdir belirtebilir 6 << 1
eşdeğerdir 6 * 2
ve 6 << 3
eşdeğerdir 6 * 8
. İyi bir optimize edici derleyici, çarpmaların yerini mümkün olduğunda vardiyalarla değiştirecektir.
Dairesel olmayan kaydırma
Bunların dairesel vardiya olmadığını lütfen unutmayın . Bu değeri bir konum sola kaydırmak ( 3,758,096,384 << 1
):
11100000 00000000 00000000 00000000
3,221,225,472 sonuç:
11000000 00000000 00000000 00000000
"Sondan" kaymış olan basamak kaybolur. Etrafına sarılmaz.
Mantıksal sağ kaydırma (>>>)
Mantıksal bir sağ kaydırma, sol kaydırmanın tersidir. Bitleri sola hareket ettirmek yerine, sadece sağa hareket ederler. Örneğin, 12 sayısını değiştirmek:
00000000 00000000 00000000 00001100
bir konum sağa ( 12 >>> 1
) orijinal 6'mızı geri alır:
00000000 00000000 00000000 00000110
Bu yüzden sağa kaymanın 2 gücüne bölünmeye eşdeğer olduğunu görüyoruz.
Kayıp bitler gitti
Ancak, bir vardiya "kayıp" bitleri geri alamaz. Örneğin, bu kalıbı kaydırırsak:
00111000 00000000 00000000 00000110
sol 4 pozisyona ( 939,524,102 << 4
), 2.147.483.744 elde ederiz:
10000000 00000000 00000000 01100000
ve daha sonra geri kaydırdığımızda ( (939,524,102 << 4) >>> 4
) 134,217,734 elde ederiz:
00001000 00000000 00000000 00000110
Bitlerimizi kaybettikten sonra orijinal değerimizi geri alamayız.
Aritmetik sağa kaydırma (>>)
Aritmetik sağ kayma tam olarak mantıksal sağ kaymaya benzer, sıfırla doldurmak yerine en önemli bitle doldurur. Bunun nedeni, en önemli bitin işaret biti veya pozitif ve negatif sayıları ayıran bit olmasıdır. En önemli bit ile dolgu yaparak, aritmetik sağ kaydırma işaret koruyucudur.
Örneğin, bu bit desenini negatif bir sayı olarak yorumlarsak:
10000000 00000000 00000000 01100000
-2,147,483,552 numaramız var. Bunu aritmetik kayma (-2,147,483,552 >> 4) ile sağ 4 konuma kaydırmak bize şu sonuçları verecektir:
11111000 00000000 00000000 00000110
veya -134,217,722 sayısı.
Dolayısıyla, mantıksal sağ kayma yerine aritmetik sağ kaymayı kullanarak negatif sayılarımızın işaretini koruduğumuzu görüyoruz. Ve bir kez daha görüyoruz ki, 2 gücüne göre bölünme yapıyoruz.