Bagaimana cara kerja operator pelengkap bitwise (~ tilde)?


Jawaban:


282

Ingat bahwa angka negatif disimpan sebagai pelengkap pasangan positif. Sebagai contoh, inilah representasi -2 dalam komplemen dua: (8 bit)

1111 1110

Cara Anda mendapatkan ini adalah dengan mengambil representasi biner dari angka, mengambil komplemennya (membalikkan semua bit) dan menambahkannya. Dua dimulai sebagai 0000 0010, dan dengan membalik bit kita mendapatkan 1111 1101. Menambahkan satu memberi kita hasil di atas. Bit pertama adalah bit tanda, menyiratkan negatif.

Jadi mari kita lihat bagaimana kita mendapatkan ~ 2 = -3:

Ini dua lagi:

0000 0010

Cukup balik semua bit dan kita dapatkan:

1111 1101

Nah, seperti apa -3 dalam komplemen dua? Mulailah dengan positif 3: 0000 0011, balik semua bit ke 1111 1100, dan tambahkan satu menjadi nilai negatif (-3), 1111 1101.

Jadi jika Anda hanya membalikkan bit dalam 2, Anda mendapatkan representasi komplemen dua -3.

Operator pelengkap (~) JUST FLIPS BITS. Terserah mesin untuk menafsirkan bit-bit ini.


43
Satu hal lain yang mungkin untuk disebutkan adalah bahwa flip disebut komplemen 1s, sebelum menambahkan 1.
Chris S

3
Ini dapat membantu orang lain yang tidak mengetahui Komplemen Satu dan Komplemen Dua. Baca tentang mereka di sini. en.wikipedia.org/wiki/Ones%27_complement en.wikipedia.org/wiki/Two%27s_complement
Sai

1
Bukankah itu operator bitwise BUKAN?
Braden Best

3
Bagaimana mesin tahu itu mendapatkan dua angka negatif komplemen dan bukan angka positif yang lebih tinggi? Apakah karena sistem tipe bahasa masing-masing menunjukkan bahwa jenisnya adalah int yang ditandatangani versus yang tidak ditandatangani?
GL2014

@ GL2014 Saya pikir Anda menjawab pertanyaan Anda sendiri di sana. Dalam pemahaman saya, itu adalah bagaimana mesin itu dirancang untuk bekerja di tempat pertama.
geekidharsh

40

~ membalik bit dalam nilai.

Mengapa ~2ada -3hubungannya dengan bagaimana angka diwakili bitwise. Angka direpresentasikan sebagai komplemen dua .

Jadi, 2 adalah nilai biner

00000010

Dan ~ 2 membalik bit sehingga nilainya sekarang:

11111101

Yang merupakan representasi biner dari -3.


2
Bukankah 11111101 == desimal 253 vs -3?
AKS

10
Tergantung jika itu mewakili bilangan bulat yang ditandatangani atau tidak ditandatangani.
driis

18

Seperti yang disebutkan orang lain ~hanya membalik bit (perubahan satu ke nol dan nol ke satu) dan karena komplemen dua digunakan Anda mendapatkan hasil yang Anda lihat.

Satu hal yang ditambahkan adalah mengapa komplemen dua digunakan, ini adalah agar operasi pada angka negatif akan sama seperti pada angka positif. Anggap -3sebagai angka yang 3harus ditambahkan untuk mendapatkan nol dan Anda akan melihat bahwa angka ini adalah 1101, ingat bahwa penambahan biner sama seperti sekolah dasar (desimal) selain hanya Anda membawa satu ketika Anda mendapatkan dua daripada 10 .

 1101 +
 0011 // 3
    =
10000
    =
 0000 // lose carry bit because integers have a constant number of bits.

Oleh karena 1101itu -3, balikkan bit yang Anda dapatkan 0010yang dua.


8

Operasi ini adalah pelengkap, bukan negasi.

Pertimbangkan itu ~ 0 = -1, dan bekerja dari sana.

Algoritma untuk negasi adalah, "komplemen, kenaikan".

Tahukah kamu? Ada juga "melengkapi satu" di mana angka-angka terbalik yang simetris, dan memiliki baik 0 dan -0.


6

Saya tahu jawaban untuk pertanyaan ini sudah diposting lama, tetapi saya ingin membagikan jawaban saya untuk hal yang sama.

Untuk menemukan pelengkap angka seseorang, pertama temukan persamaan binernya. Di sini, angka desimal 2direpresentasikan 0000 0010dalam bentuk biner. Sekarang mengambil komplemennya dengan membalik (membalik semua 1 ke 0 dan semua 0 ke 1) semua digit dari representasi binernya, yang akan menghasilkan:

0000 0010 → 1111 1101

Ini adalah komplemen satu dari angka desimal 2. Dan karena bit pertama, yaitu, bit tanda adalah 1 dalam angka biner, itu berarti bahwa tanda negatif untuk nomor yang disimpannya. (di sini, nomor yang dimaksud bukan 2 tetapi yang melengkapi 2).

Sekarang, karena angka-angka disimpan sebagai pelengkap 2 (mengambil pelengkap seseorang dari angka plus satu), jadi untuk menampilkan angka biner ini 1111 1101, menjadi desimal, pertama kita perlu menemukan pelengkap 2-nya, yang akan menjadi:

1111 1101 → 0000 0010 + 1 → 0000 0011

Ini adalah komplemen 2's. Representasi desimal dari angka biner 0000 0011,, adalah 3. Dan, karena tanda bit itu satu seperti yang disebutkan di atas, maka jawabannya adalah -3.

Petunjuk: Jika Anda membaca prosedur ini dengan cermat, maka Anda akan mengamati bahwa hasil untuk operator komplemen seseorang sebenarnya, angka (operan - yang digunakan operator ini) ditambah satu dengan tanda negatif. Anda dapat mencoba ini dengan nomor lain juga.


Mengapa menambahkan dua kali? Saya melihat add, flip, add. 0010-> 0011-> 1100->1101
Braden Best

1
Ini flip, flip, tambahkan. Balik pertama untuk komplemen 1's. Dan karena, ia disimpan dalam komplemen 2 dalam sistem, ketika Anda perlu menampilkan nomor, itu akan menunjukkan komplemen 2 dari jumlah yang disimpan (yaitu, flip kedua dan tambahkan).
Himanshu Aggarwal

Tapi bukankah flip (flip (2)) hanya menjadi 2? 0010 1101 0010
Braden Best

Ya itu akan menjadi 2 saja. Tetapi karena ketika bit disimpan dalam memori bit yang paling signifikan adalah 1 yang akan membuat angka negatif nanti seperti yang dijelaskan dalam jawaban di atas.
Himanshu Aggarwal

1
Dari apa yang Anda gambarkan dan semua yang saya teliti, ini bukan komplemen dua, tetapi komplemen "biasa", atau BUKAN sedikit pun. Dalam logika, NOT 0 = 1dan NOT 1 = 0. Dalam sistem empat-bit, NOT 0011(3) = 1100(12 tidak ditandatangani, -4 ditandatangani). Dari apa yang saya mengerti, komplemen dua didefinisikan sebagai (NOT n) + 1, dan digunakan untuk menemukan lawan negatif dari suatu angka terlepas dari jumlah bit. Jadi 2c(5) = -5,. Lihat, sekarang masuk akal. Asalkan Anda menyebut operasi ini apa adanya: bitwise TIDAK.
Braden Best

4

int a = 4; System.out.println (~ a); Hasilnya adalah: -5

'~' dari sembarang bilangan bulat di java mewakili komplemen 1 dari no. misalnya saya mengambil ~ 4, yang berarti dalam representasi biner 0100. pertama, panjang bilangan bulat adalah empat byte, yaitu 4 * 8 (8 bit untuk 1 byte) = 32. Jadi dalam memori sistem 4 direpresentasikan sebagai 0000 0000 0000 0000 0000 0000 0000 0100 sekarang ~ operator akan melakukan pelengkap 1 pada binary di atas

yaitu 1111 1111 1111 1111 1111 1111 1111 1011-> 1 melengkapi bit paling signifikan mewakili tanda tidak (baik - atau +) jika itu adalah 1 maka tanda adalah '-' jika itu 0 maka tanda adalah '+' sesuai ini hasil kami adalah angka negatif, di java angka negatif disimpan dalam bentuk komplemen 2's, hasil yang diperoleh kita harus mengkonversi ke komplemen 2's (pertama melakukan komplemen 1 dan hanya menambahkan komplemen 1 ke 1). semua yang akan menjadi nol, kecuali bit 1 yang paling signifikan (yang merupakan representasi tanda kami dari angka, yang berarti untuk sisa 31 bit 1111 1111 1111 1111 1111 1111 1111 1011 (hasil yang diperoleh dari ~ operator) 1000 0000 0000 0000 0000 0000 0000 0000 0100 (komplemen 1)

1 (komplemen 2)

1000 0000 0000 0000 0000 0000 0101 sekarang hasilnya adalah -5 periksa tautan ini untuk video <[Operator bijaksana di Jawa] https://youtu.be/w4pJ4cGWe9Y


2

Secara sederhana ...........

Sebagai komplemen 2 dari angka apa pun, kita dapat menghitung dengan membalikkan semua 1 ke 0 dan sebaliknya daripada kita menambahkan 1 ke dalamnya ..

Di sini N = ~ N menghasilkan hasil - (N +1) selalu. Karena sistem menyimpan data dalam bentuk pelengkap 2 yang artinya menyimpan ~ N seperti ini.

  ~N = -(~(~N)+1) =-(N+1). 

Sebagai contoh::

  N = 10  = 1010
  Than ~N  = 0101
  so ~(~N) = 1010
  so ~(~N) +1 = 1011 

Sekarang poinnya adalah dari mana Minus datang. Pendapat saya anggap kita memiliki register 32 bit yang berarti 2 ^ 31 -1 bit terlibat dalam operasi dan sisanya satu bit yang berubah dalam perhitungan sebelumnya (komplemen) disimpan sebagai bit tanda yang biasanya 1. Dan kami mendapatkan hasil sebagai ~ 10 = -11.

~ (-11) = 10;

Hal di atas benar jika printf ("% d", ~ 0); kami mendapatkan hasil: -1;

Tapi printf ("% u", ~ 0) dari hasil: 4294967295 pada mesin 32 bit.


1

Operator komplemen Bitwise (~) adalah operator unary .

Ini bekerja sesuai metode berikut

Pertama mengonversi angka desimal yang diberikan ke nilai biner yang sesuai . Itu dalam kasus 2, pertama mengonversi 2 menjadi 0000 0010 (menjadi angka biner 8 bit).

Kemudian mengkonversi semua angka 1 menjadi angka 0, dan semua angka nol menjadi angka 1, maka angka tersebut akan menjadi 11111 1101.

itu adalah representasi komplemen 2 dari -3.

Untuk menemukan nilai yang tidak ditandatangani menggunakan komplemen, yaitu cukup untuk mengkonversi 1111 1101 ke desimal (= 4294967293) kita dapat menggunakan% u selama pencetakan.


1

Saya pikir bagi kebanyakan orang bagian kebingungan berasal dari perbedaan antara angka desimal dan angka biner yang ditandatangani, jadi mari kita perjelas dulu:

untuk dunia desimal manusia: 01 berarti 1, -01 berarti -1, untuk dunia biner komputer: 101 berarti 5 jika tidak ditandatangani. 101 berarti (-4 +1) jika ditandatangani sementara angka yang ditandatangani berada pada posisi x. | x

sehingga bit 2 terbalik = ~ 2 = ~ (010) = 101 = -4 + 1 = -3 kebingungan berasal dari mencampuradukkan hasil yang ditandatangani (101 = -3) dan hasil yang tidak ditandai (101 = 5)


1

tl; dr ~ membalik bit. Akibatnya tanda berubah. ~2adalah angka negatif ( 0b..101). Untuk keluaran angka negatif rubycetakan -, maka komplemen dua ini dari ~2: -(~~2 + 1) == -(2 + 1) == 3. Angka positif adalah output apa adanya.

Ada nilai internal, dan representasi stringnya. Untuk bilangan bulat positif, mereka pada dasarnya bertepatan:

irb(main):001:0> '%i' % 2
=> "2"
irb(main):002:0> 2
=> 2

Yang terakhir setara dengan:

irb(main):003:0> 2.to_s
"2"

~membalik bit dari nilai internal. 2adalah 0b010. ~2adalah 0b..101. Dua titik ( ..) mewakili jumlah tak terhingga dari 1. Karena bit paling signifikan (MSB) dari hasilnya adalah 1, hasilnya adalah angka negatif ( (~2).negative? == true). Untuk rubymencetak angka negatif dicetak -, maka komplemen dua dari nilai internal. Komplemen dua dihitung dengan membalik bit, lalu menambahkan 1. Dua komplemen dari 0b..101is 3. Dengan demikian:

irb(main):005:0> '%b' % 2
=> "10"
irb(main):006:0> '%b' % ~2
=> "..101"
irb(main):007:0> ~2
=> -3

Singkatnya, itu membalik bit, yang mengubah tanda. Untuk menghasilkan angka negatif yang dicetaknya -, maka ~~2 + 1( ~~2 == 2).

Alasan mengapa rubymenghasilkan angka negatif seperti itu adalah karena ia memperlakukan nilai yang disimpan sebagai pelengkap dua dari nilai absolut. Dengan kata lain, apa yang disimpan adalah 0b..101. Ini adalah angka negatif, dan karenanya merupakan pelengkap dari beberapa nilai x. Untuk menemukan x, itu melengkapi dua 0b..101. Yang merupakan pelengkap dua dari pelengkap dua dari x. Yaitu x(misalnya ~(~2 + 1) + 1 == 2).

Jika Anda berlaku ~untuk angka negatif, itu hanya membalik bit (yang mengubah tanda):

irb(main):008:0> '%b' % -3
=> "..101"
irb(main):009:0> '%b' % ~-3
=> "10"
irb(main):010:0> ~-3
=> 2

Yang lebih membingungkan adalah ~0xffffff00 != 0xff(atau nilai lain dengan MSB sama dengan 1). Mari kita menyederhanakan sedikit: ~0xf0 != 0x0f. Itu karena memperlakukan 0xf0sebagai angka positif. Yang sebenarnya masuk akal. Jadi, ~0xf0 == 0x..f0f. Hasilnya adalah angka negatif. Dua komplemen dari 0x..f0fis 0xf1. Begitu:

irb(main):011:0> '%x' % ~0xf0
=> "..f0f"
irb(main):012:0> (~0xf0).to_s(16)
=> "-f1"

Jika Anda tidak akan menerapkan operator bitwise ke hasilnya, Anda dapat mempertimbangkan ~sebagai -x - 1operator:

irb(main):018:0> -2 - 1
=> -3
irb(main):019:0> --3 - 1
=> 2

Tapi itu bisa dibilang tidak banyak gunanya.

Contoh Katakanlah Anda diberi netmask 8-bit (untuk kesederhanaan), dan Anda ingin menghitung jumlahnya 0. Anda dapat menghitungnya dengan membalik bit dan memanggil bit_length( 0x0f.bit_length == 4). Tapi ~0xf0 == 0x..f0f, jadi kita harus memotong bit yang tidak dibutuhkan:

irb(main):014:0> '%x' % (~0xf0 & 0xff)
=> "f"
irb(main):015:0> (~0xf0 & 0xff).bit_length
=> 4

Atau Anda dapat menggunakan operator XOR ( ^):

irb(main):016:0> i = 0xf0
irb(main):017:0> '%x' % i ^ ((1 << i.bit_length) - 1)
=> "f"

0

Pertama kita harus membagi digit yang diberikan menjadi digit biner dan kemudian membalikkannya dengan menambahkan pada digit biner terakhir. Setelah eksekusi ini kita harus memberikan tanda berlawanan dengan digit sebelumnya yang kita temukan komplemen ~ 2 = -3 Penjelasan : 2s bentuk biner adalah 00000010 perubahan ke 11111101 ini adalah yang komplemen, kemudian komplemen 00000010 + 1 = 00000011 yang merupakan bentuk biner dari tiga dan dengan -sign Ie, -3


0

Operator bit-wise adalah operator unary yang bekerja dengan metode sign and magnitude sesuai pengalaman dan pengetahuan saya.

Sebagai contoh ~ 2 akan menghasilkan -3.

Ini karena operator bit-bijaksana pertama-tama akan mewakili angka dalam tanda dan besarnya yaitu 0000 0010 (operator 8 bit) di mana MSB adalah bit tanda.

Kemudian nanti akan mengambil angka negatif 2 yaitu -2.

-2 direpresentasikan sebagai 1000 0010 (operator 8 bit) dalam tanda dan besarnya.

Kemudian ia menambahkan 1 ke LSB (1000 0010 +1) yang memberi Anda 1000 0011.

Yaitu -3.


0

Javascript tilde (~) memaksa nilai yang diberikan ke komplemen seseorang - semua bit dibalik. Itu saja yang dilakukan tilde. Itu tanda tidak beralasan. Itu tidak menambah atau mengurangi jumlah apa pun.

0 -> 1
1 -> 0
...in every bit position [0...integer nbr of bits - 1]

Pada prosesor desktop standar yang menggunakan bahasa tingkat tinggi seperti JavaScript, BASE10 menandatangani aritmatika adalah yang paling umum, tetapi perlu diingat, itu bukan satu-satunya jenis. Bit pada tingkat CPU tunduk pada interpretasi berdasarkan sejumlah faktor. Pada level 'kode', dalam hal ini JavaScript, mereka ditafsirkan sebagai integer yang ditandatangani 32-bit menurut definisi (mari kita biarkan mengapung dari ini). Anggap saja sebagai kuantum, 32-bit tersebut mewakili banyak nilai yang mungkin sekaligus. Ini sepenuhnya tergantung pada lensa konversi yang Anda lihat.

JavaScript Tilde operation (1's complement)

BASE2 lens
~0001 -> 1110  - end result of ~ bitwise operation

BASE10 Signed lens (typical JS implementation)
~1  -> -2 

BASE10 Unsigned lens 
~1  -> 14 

Semua hal di atas benar pada saat bersamaan.


0

Pada dasarnya tindakan adalah pelengkap bukan negasi.

Di sini x = ~ x menghasilkan hasil - (x +1) selalu.

x = ~ 2

- (2 +1)

-3

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.