Misalkan nomor saya 'numb'=1025 [00000000 00000000 00000100 00000001]
diwakili:
Pada Mesin Little-Endian:
00000001 00000100 00000000 00000000
Pada Mesin Big-Endian:
00000000 00000000 00000100 00000001
Sekarang, jika saya menerapkan Pergeseran Kiri pada 10 bit (yaitu: mati rasa << = 10), saya harus memiliki:
[A] Pada Mesin Little-Endian:
Seperti yang saya perhatikan di GDB, Little Endian melakukan Pergeseran Kiri dalam 3 langkah: [Saya telah menunjukkan Langkah '3' untuk lebih memahami pemrosesan saja]
Obati no. dalam Konvensi Big-Endian:
00000000 00000000 00000100 00000001
Terapkan Kiri-Shift:
00000000 00010000 00000100 00000000
Mewakili Hasil lagi di Little-Endian:
00000000 00000100 00010000 00000000
[B]. Pada Mesin Big-Endian:
00000000 00010000 00000100 00000000
Pertanyaanku adalah:
Jika saya langsung menerapkan Pergeseran Kiri pada Konvensi Little Endian, itu harus memberikan:
numb
:
00000001 00000100 00000000 00000000
numb << 10
:
00010000 00000000 00000000 00000000
Tapi sebenarnya, itu memberi:
00000000 00000100 00010000 00000000
Untuk mencapai hasil kedua saja, saya telah menunjukkan tiga langkah hipotetis di atas.
Tolong jelaskan kepada saya mengapa dua hasil di atas berbeda: Hasil aktual numb << 10
berbeda dari hasil yang diharapkan.
sumber
Tidak, bitshift, seperti bagian C lainnya, didefinisikan dalam nilai , bukan representasi. Shift kiri oleh 1 adalah mutliplikasi oleh 2, shift kanan adalah pembagian. (Seperti biasa ketika menggunakan operasi bitwise, waspadalah terhadap penandatanganan. Semuanya terdefinisi dengan baik untuk tipe integral yang tidak ditandatangani.)
sumber
x &= -1u << 20
kemungkinan besar akan salah jikax
64-bit danint
32-bit. Untuk alasan ini, GCC berjanji untuk tidak pernah memperlakukan shift yang ditandatangani sebagai tidak ditentukan atau bahkan tidak ditentukan.Instruksi shift mana pun yang menggeser bit orde tinggi terlebih dahulu dianggap sebagai shift kiri. Instruksi shift mana pun yang menggeser bit orde rendah terlebih dahulu dianggap sebagai pergeseran yang tepat. Dalam hal itu, perilaku
>>
dan<<
untukunsigned
angka tidak akan bergantung pada endianness.sumber
Komputer tidak menuliskan angka seperti yang kita lakukan. Nilainya hanya bergeser. Jika Anda bersikeras melihatnya byte-by-byte (meskipun itu bukan cara komputer melakukannya), Anda bisa mengatakan bahwa pada mesin little-endian, byte pertama bergeser ke kiri, kelebihan bit masuk ke byte kedua, dan seterusnya.
(Omong-omong, little-endian lebih masuk akal jika Anda menulis byte secara vertikal daripada horizontal, dengan alamat yang lebih tinggi di atas. Yang terjadi adalah bagaimana diagram peta memori umumnya digambar.)
sumber
Meskipun jawaban yang diterima menunjukkan bahwa endianess adalah konsep dari pandangan memori. Tapi saya tidak berpikir itu menjawab pertanyaan secara langsung.
Beberapa jawaban memberi tahu saya bahwa operasi bitwise tidak bergantung pada endianess , dan prosesor dapat mewakili byte dengan cara lain. Ngomong-ngomong, itu berbicara tentang endianess yang akan diabstraksikan.
Tetapi ketika kita melakukan perhitungan bitwise di kertas misalnya, tidak perlu menyatakan endianess di tempat pertama? Seringkali kita memilih endianess secara implisit.
Misalnya, anggap kita memiliki garis kode seperti ini
0x1F & 0xEF
Bagaimana Anda menghitung hasilnya dengan tangan, di atas kertas?
Jadi di sini kita menggunakan format Big Endian untuk melakukan perhitungan. Anda juga dapat menggunakan Little Endian untuk menghitung dan mendapatkan hasil yang sama.
Btw, ketika kita menulis angka dalam kode, saya pikir itu seperti format Big Endian.
123456
atau0x1F
, angka paling signifikan dimulai dari kiri.Sekali lagi, segera setelah kita menulis beberapa format biner dari nilai di atas kertas, saya pikir kita sudah memilih Endianess dan kita melihat nilainya seperti yang kita lihat dari memori.
Jadi kembali ke pertanyaan, operasi shift
<<
harus dianggap bergeser dari LSB (byte paling signifikan) ke MSB (byte paling signifikan) .Kemudian untuk contoh dalam pertanyaan:
numb=1025
Little Endian
LSB 00000001 00000100 00000000 00000000 MSB
Jadi
<< 10
akan10bit
bergeser dari LSB ke MSB.Perbandingan dan
<< 10
operasi untuk format Little Endian langkah demi langkah:Wow! Saya mendapatkan hasil yang diharapkan seperti yang dijelaskan OP!
Masalah yang OP tidak dapatkan hasil yang diharapkan adalah:
Tampaknya dia tidak beralih dari LSB ke MSB.
Ketika menggeser bit dalam format Little Endian, Anda harus menyadari (terima kasih Tuhan, saya sadari) bahwa:
LSB 10000000 00000000 MSB << 1
adalahLSB 00000000 00000001 MSB
, tidakLSB 01000000 00000000 MSB
Karena untuk setiap individu
8bits
, kami sebenarnya menulisnya dalamMSB 00000000 LSB
format Big Endian.Jadi seperti itu
LSB[ (MSB 10000000 LSB) (MSB 00000000 LSB) ]MSB
Untuk menyimpulkan:
Meskipun operasi bitwise dikatakan diabstraksi dari blablablabla ..., ketika kita menghitung operasi bitwise dengan tangan, kita masih perlu mengetahui endianess apa yang kita gunakan saat kita menuliskan format biner di atas kertas. Kami juga perlu memastikan semua operator menggunakan endianess yang sama.
OP tidak mendapatkan hasil yang diharapkan karena dia melakukan kesalahan shifting.
sumber