Saya mencoba agar C menafsirkan bilangan bulat tak bertanda terbalik sebagai bilangan bulat tak bertanda. Bagaimana saya bisa membalikkan bit dari angka yang tidak ditandatangani tanpa C menafsirkannya sebagai pelengkap dua?

Setiap kali saya memiliki bilangan bulat yang tidak ditandatangani dan saya menggunakannya sebagai operan dengan operator NOT bitwise, ia mengevaluasi ke angka negatif sesuai dengan komplemen dua. Namun menurut definisi Saya menggunakan bilangan bulat tidak bertanda, angka yang seharusnya tidak memiliki tanda.

Di bawah ini memiliki kode kotak pasir saya. Saat ini saya menggunakan GCC versi 9.1.1.

#include <stdio.h>
#include <stdint.h>

int main(){
   uint8_t x = 1;//0000 0001
   printf("NOT(%d) == %d", x, ~x);//1111 1110
}

Saya ingin output 254 (1111 1110) tetapi C menginterpretasikan nilainya sebagai pelengkap dua jadi saya mendapatkan -2. Apakah ada cara agar C tidak menafsirkan byte terbalik sebagai pelengkap dua?

2
Milan Donhowe 6 Agustus 2019, 02:28

1 menjawab

Jawaban Terbaik

Di C, ketika bilangan bulat yang lebih sempit dari int digunakan dalam ekspresi, maka secara otomatis dipromosikan menjadi int. Jadi, dalam ~x, uint8_t secara otomatis dikonversi ke int, dan kemudian bitwise ~ dilakukan, dan hasilnya diteruskan ke printf sebagai int. Jadi yang tercetak adalah hasil dari membalik semua bit int, bukan hanya bit uint8_t.

Untuk mendapatkan hasil uint8_t, berikan ekspresi ke uint8_t:

printf("NOT(%d) == %d", x, (uint8_t) ~x);

Perhatikan bahwa setelah konversi uint8_t dilakukan, nilai secara otomatis dipromosikan menjadi int, jadi printf menerima int dalam kedua kasus tersebut. Namun, konversi mengurangi nilai menjadi satu yang dapat diwakili dalam uint8_t, dan ini adalah nilai yang akan dicetak.

Namun, konversi ke uint8_t menggunakan int sebagai jenis sumber, sehingga bit ~x akan diinterpretasikan sesuai dengan format int implementasi. Untuk mendapatkan bit rendah ~x tanpa bergantung pada format int, Anda dapat mengekstraknya dengan & 0xff daripada menggunakan gips:

printf("NOT(%d) == %d", x, ~x & 0xff);

Sebagai alternatif, Anda dapat melakukan ~ bitwise pada nilai unsigned alih-alih nilai int:

printf("NOT(%d) == %d", x, (uint8_t) ~ (unsigned) x);
5
Eric Postpischil 6 Agustus 2019, 01:24