Yanıtlar:
Negatif sayıların ikisinin pozitif karşılığı tamamlayıcısı olarak saklandığını unutmayın . Örnek olarak, burada ikinin tamamlayıcısında -2'nin temsili: (8 bit)
1111 1110
Bunu elde etmenin yolu, bir sayının ikili temsilini almak, tamamlayıcısını almak (tüm bitleri tersine çevirmek) ve bir sayı eklemektir. İkisi 0000 0010 olarak başlar ve bitleri tersine çevirerek 1111 1101 elde ederiz. Bir tane eklemek bize yukarıdaki sonucu getirir. İlk bit, işaret bitidir, negatif anlamına gelir.
Öyleyse nasıl elde ettiğimize bir bakalım ~ 2 = -3:
İşte yine iki tane:
0000 0010
Sadece tüm bitleri çevirin ve elde ederiz:
1111 1101
Peki, ikisinin tamamlayıcısı -3'e benziyor mu? Pozitif 3: 0000 0011 ile başlayın, tüm bitleri 1111 1100'e çevirin ve negatif değer (-3), 1111 1101 olmak için bir tane ekleyin.
Eğer bitleri 2'de ters çevirirseniz, ikisinin -3'ü tamamlayıcı gösterimini elde edersiniz.
~
değerdeki bitleri çevirir.
Neden ~2
olduğu -3
sayılar bit düzeyinde temsil edildiği nasıl bir ilgisi vardır. Sayılar ikinin tamamlayıcısı olarak temsil edilir .
Yani, 2 ikili değerdir
00000010
Ve ~ 2 bitleri çevirir, böylece değer şu şekildedir:
11111101
Ki, -3'ün ikili temsilidir.
Diğerlerinin de belirttiği gibi ~
sadece çevrilmiş bitler (bir sıfıra ve sıfır bire) ve ikisinin tamamlayıcısı kullanıldığından gördüğünüz sonucu elde edersiniz.
Eklenecek bir şey, ikinin tamamlayıcısının neden kullanıldığıdır, bu yüzden negatif sayılardaki işlemler pozitif sayılarla aynı olacaktır. Sıfır elde etmek için eklenecek -3
sayı olarak düşünün 3
ve bu sayının olduğunu göreceksiniz 1101
, ikili eklemenin tıpkı ilkokul (ondalık) toplama gibi olduğunu unutmayın. .
1101 +
0011 // 3
=
10000
=
0000 // lose carry bit because integers have a constant number of bits.
Bu nedenle 1101
, -3
aldığınız bitleri 0010
iki olan çevirin .
Bu sorunun cevabının uzun bir süre geri gönderildiğini biliyorum, ama aynı cevabımı paylaşmak istedim.
Kişinin bir sayıyı tamamlaması için önce ikili eşdeğerini bulun. Burada, ondalık sayı ikili biçimde 2
temsil edilir 0000 0010
. Şimdi, ikili temsilinin tüm rakamlarını tersine çevirerek (1'lerin hepsini 0'lara ve 0'ları 1'lere çevirerek) tamamlayıcısını alarak, aşağıdakilerle sonuçlanacaktır:
0000 0010 → 1111 1101
Bu, ondalık sayı 2'nin tamamlayıcısıdır. Ve ilk bit, yani, işaret biti ikili sayıda 1 olduğundan, işaretin depoladığı sayı için negatif olduğu anlamına gelir . (burada, atıfta bulunulan sayı değil 2 değil 2 kişinin tamamlayıcısı).
Şimdi, sayılar 2'nin tamamlayıcısı olarak saklandığından (kişinin bir sayısını artı birini tamamlar), bu yüzden bu ikili sayıyı görüntülemek için, 1111 1101
ondalık olarak, önce 2'sinin tamamlayıcısını bulmamız gerekir, bu da:
1111 1101 → 0000 0010 + 1 → 0000 0011
Bu 2'nin tamamlayıcısıdır. İkili sayının ondalık gösterimi 0000 0011
,, 3
. Ve, işaret biti yukarıda belirtildiği gibi olduğu için, sonuçta ortaya çıkan cevap -3
.
İpucu: Bu prosedürü dikkatlice okursanız, kişinin tamamlayıcı operatörünün sonucunun aslında, bu operatörün uygulandığı sayı (işlenen - işlenen) artı bir negatif işaretli olduğunu gözlemlediniz. Bunu diğer numaralarla da deneyebilirsiniz.
add, flip, add
. 0010
-> 0011
-> 1100
->1101
0010
1101
0010
NOT 0 = 1
ve NOT 1 = 0
. Dört bitlik bir sistemde, NOT 0011
(3) = 1100
(12 imzasız, -4 imzalı). Anladığım kadarıyla, ikisinin tamamlayıcısı olarak tanımlanır (NOT n) + 1
ve bit sayısına bakılmaksızın bir sayının negatif karşılığını bulmak için kullanılır. Böylece 2c(5) = -5
,. Bakın, şimdi mantıklı. Bu işlemi çağırdığınız sürece ne olduğu: bir bitwise NOT.
int a = 4; System.out.println (~ a); Sonuç: -5
Java'daki herhangi bir tam sayının '~' değeri, 1'in no. örneğin ~ 4 alıyorum, yani ikili gösterimde 0100 anlamına gelir. ilk olarak, bir tamsayının uzunluğu dört bayttır, yani 4 * 8 (1 bayt için 8 bit) = 32. Böylece sistem belleğinde 4, 0000 0000 0000 0000 0000 0000 0000 0000 0100 olarak temsil edilir ~ operatör yukarıdaki ikili nota 1'in tamamlayıcısını gerçekleştirir.
yani 1111 1111 1111 1111 1111 1111 1111 1011-> 1'in tamamlayıcısı, en önemli bit, 1 ise hayır işaretini (ya - ya da +) temsil eder, eğer 0 ise işaret '-' olur, işaret ise '+' Bu bizim sonucumuz negatif bir sayıdır, java'da negatif sayılar 2'nin tamamlayıcı formunda saklanır, elde edilen sonuç 2'nin tamamlayıcısına dönüştürmeliyiz (önce 1'in tamamlayıcısını gerçekleştirin ve sadece 1'e 1 tamamlayıcısını ekleyin). en önemli bit 1 (sayının işaret temsili olan, yani kalan 31 bit 1111 1111 1111 1111 1111 1111 1111 1011 (~ operatörünün elde ettiği sonuç) hariç tümü sıfır olacak) 1000 0000 0000 0000 0000 0000 0000 0000 0100 (1'in tamamlayıcısı)
1000 0000 0000 0000 0000 0000 0000 0000 0000 0101 şimdi sonuç -5 video için bu bağlantıyı kontrol edin <[Java'da bit bilge operatörler] https://youtu.be/w4pJ4cGWe9Y
Basitçe ...........
2'nin herhangi bir sayıyı tamamlaması olarak, 1'leri 0'lara ve tersini 1'e ekleyerek hesaplayabiliriz.
Burada N = ~ N sonuçları üretir - (N + 1) her zaman. Çünkü sistem verileri 2'nin tamamlayıcısı biçiminde depolar, yani ~ N bunu depolar.
~N = -(~(~N)+1) =-(N+1).
Örneğin::
N = 10 = 1010
Than ~N = 0101
so ~(~N) = 1010
so ~(~N) +1 = 1011
Şimdi nokta, Eksi'nin geldiği yerdir. Bence 32 bit kayıt var, yani operasyonda 2 ^ 31 -1 bit anlamına gelir ve genellikle 1 olan işaret biti olarak saklanan önceki hesaplamada (tamamlayıcı) değişiklik olan bir bit dinlenmek demektir. Ve sonucu ~ 10 = -11 olarak alıyoruz.
% (-11) = 10;
Yukarıdakiler doğruysa printf ("% d", ~ 0); sonuç alırız: -1;
Ancak printf ("% u", ~ 0) sonuçtan: 329 bit makinede 4294967295.
Bitsel tamamlayıcı operatörü (~) tekli bir operatördür.
Aşağıdaki yöntemlere göre çalışır
Önce verilen ondalık sayıyı karşılık gelen ikili değerine dönüştürür. 2 olması durumunda önce 2'yi 0000 0010'a (8 bit ikili sayıya) dönüştürür.
Daha sonra sayıdaki tüm 1'i 0'a ve tüm sıfırları 1'e dönüştürür; sonra sayı 1111 1101 olur.
bu 2'nin -3'ün tamamlayıcı temsilidir.
Tamamlayıcı kullanarak imzasız değeri bulmak için, yani sadece 1111 1101'i ondalığa (= 4294967293) dönüştürmek için, yazdırma sırasında% u kullanabiliriz.
Çoğu insan için karışıklık kısmı ondalık sayı ve imzalı ikili sayı arasındaki farktan geliyor, bu yüzden önce açıklığa kavuşalım:
insan ondalık dünyası için: 01 1, -01 -1 anlamına gelir, bilgisayarın ikili dünyası için: 101 imzalanmamışsa 5 anlamına gelir. 101, işaretli rakam x konumundayken imzalanmışsa (-4 + 1) anlamına gelir. | x
2'nin çevrilmiş biti = ~ 2 = ~ (010) = 101 = -4 + 1 = -3 karışıklık, imzalı sonucu (101 = -3) ve izlenmemiş sonucu (101 = 5) karıştırmaktan kaynaklanıyor.
tl; dr ~
bitleri çevirir. Sonuç olarak işaret değişir. ~2
negatif bir sayıdır ( 0b..101
). Çıkış için negatif bir sayı ruby
baskılar -
ardından, ikinin tamamlayıcısı ~2
: -(~~2 + 1) == -(2 + 1) == 3
. Pozitif sayılar olduğu gibi verilir.
Bir iç değer ve dize temsili vardır. Pozitif tamsayılar için temel olarak çakışırlar:
irb(main):001:0> '%i' % 2
=> "2"
irb(main):002:0> 2
=> 2
İkincisi şuna eşittir:
irb(main):003:0> 2.to_s
"2"
~
dahili değerin bitlerini çevirir. 2
olduğunu 0b010
. ~2
olduğunu 0b..101
. İki nokta ( ..
) sonsuz sayıda 1
' yı temsil eder . Sonucun en önemli biti (MSB) olduğundan sonuç 1
negatif bir sayıdır ( (~2).negative? == true
). Negatif bir sayı çıktı için ruby
baskı -
, daha sonra iç değerinin iki tamamlayıcısı. İkinin tamamlayıcısı, bitleri çevirip sonra ekleyerek hesaplanır 1
. İkinin tamamlayıcısı 0b..101
olduğunu 3
. Gibi:
irb(main):005:0> '%b' % 2
=> "10"
irb(main):006:0> '%b' % ~2
=> "..101"
irb(main):007:0> ~2
=> -3
Özetlemek gerekirse, işareti değiştiren bitleri çevirir. Negatif bir sayı çıkarmak için yazdırır -
, sonra ~~2 + 1
( ~~2 == 2
).
Bunun ruby
gibi negatif sayılar çıkarmanın nedeni, depolanan değeri ikisinin mutlak değeri tamamlayıcısı olarak görmesidir. Başka bir deyişle, depolanan şey 0b..101
. Bu negatif bir sayıdır ve bu nedenle ikisinin bir değeri tamamlamasıdır x
. Bulmak x
için, ikisini tamamlar 0b..101
. Hangi ikisinin tamamlayıcısı olan ikisinin tamamlayıcısıdır x
. Hangisi x
(örneğin ~(~2 + 1) + 1 == 2
).
~
Negatif bir sayıya başvurmanız durumunda , sadece bitleri çevirir (yine de işareti değiştirir):
irb(main):008:0> '%b' % -3
=> "..101"
irb(main):009:0> '%b' % ~-3
=> "10"
irb(main):010:0> ~-3
=> 2
Daha kafa karıştırıcı olan şey ~0xffffff00 != 0xff
(veya MSB ile eşit olan başka bir değer 1
). Hadi biraz basitleştirmek edelim: ~0xf0 != 0x0f
. Çünkü 0xf0
pozitif bir sayı gibi davranır . Bu aslında mantıklı. Yani ~0xf0 == 0x..f0f
,. Sonuç negatif bir sayıdır. İkinin tamamlayıcısı 0x..f0f
olduğunu 0xf1
. Yani:
irb(main):011:0> '%x' % ~0xf0
=> "..f0f"
irb(main):012:0> (~0xf0).to_s(16)
=> "-f1"
Sonuca bitsel işleçler uygulamazsanız, ~
bir -x - 1
işleç olarak düşünebilirsiniz :
irb(main):018:0> -2 - 1
=> -3
irb(main):019:0> --3 - 1
=> 2
Ama bu tartışmasız pek bir işe yaramıyor.
Bir örnek Diyelim ki 8 bitlik (basitlik için) bir ağ maskesi verilmiş ve 0
's sayısını hesaplamak istiyorsunuz . Bunları bitleri çevirerek bit_length
( 0x0f.bit_length == 4
) çağırarak hesaplayabilirsiniz . Ancak ~0xf0 == 0x..f0f
, gereksiz bitleri kesmemiz gerekiyor:
irb(main):014:0> '%x' % (~0xf0 & 0xff)
=> "f"
irb(main):015:0> (~0xf0 & 0xff).bit_length
=> 4
Veya XOR işlecini ( ^
) kullanabilirsiniz:
irb(main):016:0> i = 0xf0
irb(main):017:0> '%x' % i ^ ((1 << i.bit_length) - 1)
=> "f"
İlk önce verilen rakamı ikili rakamlara bölmeliyiz ve daha sonra son ikili rakamı ekleyerek tersine çevirmeliyiz. : 2s ikili form 00000010 11111101 değişiklik bu tamamlayıcı olduğunu, daha sonra tamamlandı 00000010 + 1 = 00000011 üç ikili form ve -ign Ie, -3 ile
Bit-bilge operatör benim deneyim ve bilgime göre işaret ve büyüklük yöntemi üzerinde çalışan bir tek operatör.
Örneğin ~ 2 -3 ile sonuçlanır.
Bunun nedeni, bit-bilge operatörün öncelikle MSB'nin işaret biti olduğu 0000 0010 (8 bit operatör) olan işaret ve büyüklükteki sayıyı temsil etmesidir.
Daha sonra 2 olan negatif sayıyı -2 alır.
-2, işaret ve büyüklükte 1000 0010 (8 bit operatör) olarak temsil edilir.
Daha sonra LSB'ye (1000 0010 + 1) 1 ekleyerek 1000 0011 verir.
Ki -3.
Javascript tilde (~) belirli bir değeri kişinin tamamlayıcısına zorlar - tüm bitler ters çevrilir. Hepsi tilde yapar. Görüşlü bir işaret değil. Herhangi bir miktar katmaz veya çıkarmaz.
0 -> 1
1 -> 0
...in every bit position [0...integer nbr of bits - 1]
JavaScript gibi üst düzey dilleri kullanan standart masaüstü işlemcilerinde, BASE10 imzalı aritmetik en yaygın olanıdır, ancak unutmayın, tek tür değildir. CPU seviyesindeki bitler, bir dizi faktöre dayalı olarak yoruma tabidir. 'Kod' düzeyinde, bu durumda JavaScript, tanım gereği 32 bit işaretli bir tamsayı olarak yorumlanırlar (bunun dışında kayarız). Bunu kuantum olarak düşünün, bu 32 bit bir kerede birçok olası değeri temsil ediyor. Tamamen onları görüntülediğiniz dönüştürücü lense bağlıdır.
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
Yukarıdakilerin hepsi aynı anda doğrudur.