>`) 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!