Aracılığıyla paylaş


Sol shift ve sağ shift işleçleri: << ve >>

Bit düzeyinde kaydırma işleçleri, bir tamsayı veya numaralandırma türü ifadesinin bitlerini sağa taşıyan sağ shift işlecidir>> () ve bitleri sola taşıyan sol kaydırma işlecidir (<< ). 1

Sözdizimi

shift-expression:
additive-expression
shift-expression << additive-expression
shift-expression >> additive-expression

Açıklamalar

Önemli

Aşağıdaki açıklamalar ve örnekler, x86 ve x64 mimarileri için Windows'ta geçerlidir. ARM cihazları için Windows'ta sol vardiya ve sağ vardiya işleçlerinin uygulanması önemli ölçüde farklıdır. Daha fazla bilgi için Hello ARM blog gönderisinin "Shift Operators" bölümüne bakın.

Sola Kaydırmalar

left-shift işleci, içindeki bitlerin shift-expression tarafından additive-expressionbelirtilen konum sayısıyla sola kaydırılmasına neden olur. Kaydırma işleci tarafından boşaltılmış bit konumları sıfır dolguludur. Sola kaydırma mantıksal bir kaydırmadır (imza biti dahil, sona kaydırılan bitler atılır). Bit düzeyinde kaydırma türleri hakkında daha fazla bilgi için bkz . Bit düzeyinde kaydırmalar.

Aşağıdaki örnek, işaretsiz sayıların kullanıldığı sola kaydırma işleçlerini gösterir. Bu örnek değeri bir bit kümesi olarak temsil eden bitlere ne olduğunu göstermektedir. Daha fazla bilgi için bkz . bitset Sınıfı.

#include <iostream>
#include <bitset>

using namespace std;

int main() {
    unsigned short short1 = 4;
    bitset<16> bitset1{short1};   // the bitset representation of 4
    cout << bitset1 << endl;  // 0b00000000'00000100

    unsigned short short2 = short1 << 1;     // 4 left-shifted by 1 = 8
    bitset<16> bitset2{short2};
    cout << bitset2 << endl;  // 0b00000000'00001000

    unsigned short short3 = short1 << 2;     // 4 left-shifted by 2 = 16
    bitset<16> bitset3{short3};
    cout << bitset3 << endl;  // 0b00000000'00010000
}

İşaretli bir sayıyı sola kaydırırsanız, imza biti etkilenir ve sonuç tanımsız olur. Aşağıdaki örnekte, 1 bit sola işaret biti konumuna kaydırıldığında ne olacağı gösterilmektedir.

#include <iostream>
#include <bitset>

using namespace std;

int main() {
    short short1 = 16384;
    bitset<16> bitset1(short1);
    cout << bitset1 << endl;  // 0b01000000'00000000

    short short3 = short1 << 1;
    bitset<16> bitset3(short3);  // 16384 left-shifted by 1 = -32768
    cout << bitset3 << endl;  // 0b10000000'00000000

    short short4 = short1 << 14;
    bitset<16> bitset4(short4);  // 4 left-shifted by 14 = 0
    cout << bitset4 << endl;  // 0b00000000'00000000
}

Sağa Kaydırmalar

right-shift işleci, içinde bit deseninin shift-expression tarafından additive-expressionbelirtilen konum sayısıyla sağa kaydırılmasına neden olur. İşaretsiz sayılar için, kaydırma işleci tarafından boşaltılmış bit konumları sıfır dolguludur. İşaretli sayılar için, imza biti boşaltılmış bit konumlarını doldurmak için kullanılır. Başka bir deyişle, sayı pozitif ise 0 kullanılır ve sayı negatif ise 1 kullanılır.

Önemli

İmzalı bir negatif sayının sağ kaydırmasının sonucu uygulama bağımlıdır. Microsoft C++ derleyicisi, boş bit konumlarını doldurmak için işaret bitini kullansa da, diğer uygulamaların da bunu yapacağının garantisi yoktur.

Bu örnek, işaretsiz sayıların kullanıldığı sağa kaydırma işleçlerini gösterir:

#include <iostream>
#include <bitset>

using namespace std;

int main() {
    unsigned short short11 = 1024;
    bitset<16> bitset11{short11};
    cout << bitset11 << endl;     // 0b00000100'00000000

    unsigned short short12 = short11 >> 1;  // 512
    bitset<16> bitset12{short12};
    cout << bitset12 << endl;     // 0b00000010'00000000

    unsigned short short13 = short11 >> 10;  // 1
    bitset<16> bitset13{short13};
    cout << bitset13 << endl;     // 0b00000000'00000001

    unsigned short short14 = short11 >> 11;  // 0
    bitset<16> bitset14{short14};
    cout << bitset14 << endl;     // 0b00000000'00000000
}

Sonraki örnek, pozitif işaretli sayılara sahip sağa kaydırma işleçlerini gösterir.

#include <iostream>
#include <bitset>

using namespace std;

int main() {
    short short1 = 1024;
    bitset<16> bitset1(short1);
    cout << bitset1 << endl;     // 0b00000100'00000000

    short short2 = short1 >> 1;  // 512
    bitset<16> bitset2(short2);
    cout << bitset2 << endl;     // 0b00000010'00000000

    short short3 = short1 >> 11;  // 0
    bitset<16> bitset3(short3);
    cout << bitset3 << endl;     // 0b00000000'00000000
}

Sonraki örnek, negatif işaretli tamsayılara sahip sağa kaydırma işleçlerini gösterir.

#include <iostream>
#include <bitset>

using namespace std;

int main() {
    short neg1 = -16;
    bitset<16> bn1(neg1);
    cout << bn1 << endl;  // 0b11111111'11110000

    short neg2 = neg1 >> 1; // -8
    bitset<16> bn2(neg2);
    cout << bn2 << endl;  // 0b11111111'11111000

    short neg3 = neg1 >> 2; // -4
    bitset<16> bn3(neg3);
    cout << bn3 << endl;  // 0b11111111'11111100

    short neg4 = neg1 >> 4; // -1
    bitset<16> bn4(neg4);
    cout << bn4 << endl;  // 0b11111111'11111111

    short neg5 = neg1 >> 5; // -1
    bitset<16> bn5(neg5);
    cout << bn5 << endl;  // 0b11111111'11111111
}

Vardiyalar ve promosyonlar

Bir kaydırma işlecinin her iki tarafındaki ifadelerin de tamsayı türünde olması gerekir. İntegral yükseltmeler, Standart Dönüşümler'de açıklanan kurallara göre gerçekleştirilir. Sonucun türü, yükseltilen shift-expressionöğesinin türüyle aynıdır.

Aşağıdaki örnekte, türünde char bir değişken olarak intyükseltilir.

#include <iostream>
#include <typeinfo>

using namespace std;

int main() {
    char char1 = 'a';

    auto promoted1 = char1 << 1;   // 194
    cout << typeid(promoted1).name() << endl;  // int

    auto promoted2 = char1 << 10;  // 99328
    cout << typeid(promoted2).name() << endl;  // int
}

Ayrıntılar

Bir vardiya işleminin sonucu, negatifse additive-expression veya içindeki bit sayısından büyük veya buna eşitse additive-expression (yükseltilir) shift-expressiontanımlanmamıştır. 0 ise additive-expression vardiya işlemi gerçekleşmez.

#include <iostream>
#include <bitset>

using namespace std;

int main() {
    unsigned int int1 = 4;
    bitset<32> b1{int1};
    cout << b1 << endl;    // 0b00000000'00000000'00000000'00000100

    unsigned int int2 = int1 << -3;  // C4293: '<<' : shift count negative or too big, undefined behavior
    unsigned int int3 = int1 >> -3;  // C4293: '>>' : shift count negative or too big, undefined behavior
    unsigned int int4 = int1 << 32;  // C4293: '<<' : shift count negative or too big, undefined behavior
    unsigned int int5 = int1 >> 32;  // C4293: '>>' : shift count negative or too big, undefined behavior
    unsigned int int6 = int1 << 0;
    bitset<32> b6{int6};
    cout << b6 << endl;    // 0b00000000'00000000'00000000'00000100 (no change)
}

Dipnotlar

1 C++11 ISO belirtimindeki (INCITS/ISO/IEC 14882-2011[2012]), bölüm 5.8.2 ve 5.8.3'teki vardiya işleçlerinin açıklaması aşağıdadır.

değeri E1 << E2 sola kaydırılmış E2 bit konumlarıdırE1; boş bitler sıfır dolguludur. İmzasız bir türe sahipseE1, sonucun değeri E1 × 2E2'dir ve azaltılmış modül, sonuç türünde temsil edilebilen maksimum değerden bir fazladır. Aksi takdirde, imzalı bir türe ve negatif olmayan bir değere sahipse E1 ve E1 × 2E2 sonuç türünün karşılık gelen imzasız türünde temsil edilebilirse, sonuç türüne dönüştürülen değer sonuç değeridir; aksi takdirde davranış tanımlanmamış olur.

değeri E1 >> E2 sağ kaydırmalı E2 bit konumlarıdırE1. İmzasız bir türe sahipse E1 veya imzalı bir türe ve negatif olmayan bir değere sahipseE1, sonucun değeri E1/2 E2 bölümünün tamsayı parçasıdır. İmzalı bir türe ve negatif bir değere sahipse E1 , sonuçta elde edilen değer uygulama tanımlıdır.

Ayrıca bkz.

İkili işleçleri olan ifadeler
C++ yerleşik işleçleri, önceliği ve ilişkilendirilebilirliği