Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapakah operator anjakan kanan (`>>`) dalam C menghasilkan keputusan yang tidak dijangka apabila beralih sebanyak 32 bit?

Mengapakah operator anjakan kanan (`>>`) dalam C menghasilkan keputusan yang tidak dijangka apabila beralih sebanyak 32 bit?

DDD
DDDasal
2024-10-25 10:17:02377semak imbas

Why does the right shift operator (`>>`) dalam C menghasilkan hasil yang tidak dijangka apabila beralih sebanyak 32 bit?
>`) dalam C menghasilkan hasil yang tidak dijangka apabila beralih sebanyak 32 bit? " />

Gelagat Tidak Dijangka Operator Shift Kanan (1 >> 32)

Dalam bidang pengaturcaraan, operator shift kanan (>> ) biasanya digunakan untuk melakukan operasi bitwise, terutamanya untuk membahagikan integer dengan kuasa dua Walau bagaimanapun, tingkah laku pelik boleh timbul apabila beralih dengan nilai yang lebih besar, seperti yang ditunjukkan oleh kod C berikut:

<code class="cpp">int foo(int a, int b) {
   return a >> b;
}

int bar(uint64_t a, int b) {
   return a >> b;
}

int main() {
    std::cout << "foo(1, 32): " << foo(1, 32) << std::endl;
    std::cout << "bar(1, 32): " << bar(1, 32) << std::endl;
    std::cout << "1 >> 32: " << (1 >> 32) << std::endl; //warning here
    std::cout << "(int)1 >> (int)32: " << ((int)1 >> (int)32) << std::endl; //warning here
}

Mengejutkan. , output program ini mendedahkan hasil yang tidak dijangka:

foo(1, 32): 1 // Should be 0
bar(1, 32): 0
1 >> 32: 0
(int)1 >> (int)32: 0</code>

Rasional di sebalik keputusan ini terletak pada kerja dalaman CPU dan pengkompil.

Tingkah laku foo() Fungsi

Dalam fungsi foo(), operasi anjakan dilakukan tanpa cast, membawa CPU melakukan anjakan kanan logik Pada banyak seni bina, anjakan kanan logik dilaksanakan sebagai > > (b % 32), dengan berkesan mengabaikan bit atas b Oleh itu, foo(1, 32) menghasilkan 1 >>

Mengapa Menghantar kepada Integer 64-bit Penting?

Dalam fungsi bar(), integer tidak bertanda 64-bit disediakan, memastikan hasilnya dijamin menjadi 0 kerana b (32) adalah kurang daripada bilangan bit dalam operan (64). Walau bagaimanapun, apabila b ditukar kepada 64, hasilnya menjadi tidak dapat diramalkan dan mungkin masih menghasilkan 1.

Pengoptimuman Pengkompil

Dalam kes 1 >> 32 dan (int)1 >> (int)32, pengkompil mengoptimumkan ungkapan malar ini pada masa penyusunan. Piawaian menentukan tingkah laku yang tidak ditentukan untuk anjakan kanan di mana kiraan adalah negatif atau lebih besar daripada atau sama dengan panjang operan. Memandangkan 32 melebihi panjang operan, pengkompil tidak boleh menentukan hasil dan output 0 sebagai sandaran yang selamat.

Gelagat Khusus CPU

Pelaksanaan anjakan kanan operasi boleh berbeza-beza merentas CPU yang berbeza. Pada seni bina x86/x86-64, anjakan kanan logik secara berkesan adalah >> (b % 32 atau 64), bergantung pada mod. Walau bagaimanapun, pada pemproses ARM, operasi anjakan yang betul menjamin sifar untuk anjakan yang lebih besar daripada atau sama dengan 32.

Kesimpulan

Apabila bekerja dengan operator syif yang betul, ia adalah penting untuk mempertimbangkan potensi tingkah laku yang tidak ditentukan, terutamanya apabila kiraan anjakan melebihi panjang operan. Menghantar kepada jenis integer yang lebih luas, seperti integer 64-bit, boleh memastikan hasil yang konsisten merentas CPU dan pengkompil yang berbeza.

Atas ialah kandungan terperinci Mengapakah operator anjakan kanan (`>>`) dalam C menghasilkan keputusan yang tidak dijangka apabila beralih sebanyak 32 bit?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn