Dlaczego ~ 2 jest równe -3? Jak działa ~
operator?
Dlaczego ~ 2 jest równe -3? Jak działa ~
operator?
Pamiętaj, że liczby ujemne są przechowywane jako uzupełnienie dwóch dodatnich odpowiedników. Jako przykład, oto reprezentacja -2 w uzupełnieniu do dwóch: (8 bitów)
1111 1110
W ten sposób otrzymujesz binarną reprezentację liczby, przyjmując jej uzupełnienie (odwracając wszystkie bity) i dodając jedną. Dwa zaczynają się od 0000 0010, a przez odwrócenie bitów otrzymujemy 1111 1101. Dodanie jednego powoduje otrzymanie powyższego wyniku. Pierwszy bit jest bitem znaku, co oznacza wartość ujemną.
Przyjrzyjmy się więc, w jaki sposób otrzymujemy ~ 2 = -3:
Oto dwa znowu:
0000 0010
Po prostu odwróć wszystkie bity, a otrzymamy:
1111 1101
Jak wygląda -3 w uzupełnieniu do dwóch? Zacznij od dodatniej 3: 0000 0011, odwróć wszystkie bity na 1111 1100 i dodaj jeden, aby uzyskać wartość ujemną (-3), 1111 1101.
Więc jeśli po prostu odwrócisz bity w 2, otrzymasz reprezentację uzupełnienia dwóch -3.
~
odwraca bity wartości.Dlaczego
~2
to-3
ma wspólnego z tym, jak numery są reprezentowane bitowe. Liczby są reprezentowane jako uzupełnienie dwóch .Zatem 2 jest wartością binarną
I ~ 2 odwraca bity, więc wartość wynosi teraz:
Który jest reprezentacją binarną -3.
źródło
Jak wspomnieli inni,
~
po prostu odwrócone bity (zmienia jeden na zero i zero na jeden), a ponieważ używane jest uzupełnienie dwóch , otrzymujesz wynik, który widziałeś.Jedną rzeczą do dodania jest to, dlaczego stosowane jest uzupełnienie do dwóch, jest to tak, że operacje na liczbach ujemnych będą takie same jak na liczbach dodatnich. Pomyśl o
-3
liczbie, do której3
należy dodać, aby uzyskać zero, a zobaczysz, że ta liczba jest1101
, pamiętaj, że dodawanie binarne jest podobne do dodawania do szkoły podstawowej (dziesiętnej), tyle że nosisz jeden, gdy osiągasz dwa, a nie 10 .W związku z tym
1101
jest-3
, odwracanie bitów dostaniesz0010
który wynosi dwa.źródło
Ta operacja jest uzupełnieniem, a nie negacją.
Weź pod uwagę, że ~ 0 = -1 i pracuj stamtąd.
Algorytmem negacji jest „uzupełnienie, przyrost”.
Czy wiedziałeś? Istnieje również „uzupełnienie”, w którym liczby odwrotne są symetryczne i ma zarówno 0, jak i -0.
źródło
Wiem, że odpowiedź na to pytanie została opublikowana dawno temu, ale chciałem udostępnić swoją odpowiedź za to samo.
Aby znaleźć uzupełnienie liczby, najpierw znajdź jej binarny odpowiednik. Tutaj liczba dziesiętna
2
jest reprezentowana0000 0010
w postaci binarnej. Teraz bierzemy jego dopełnienie poprzez odwrócenie (odwrócenie wszystkich 1 na 0 i wszystkie 0 na 1) wszystkie cyfry jego reprezentacji binarnej, co spowoduje:Jest to uzupełnienie liczby dziesiętnej 2. A ponieważ pierwszy bit, tj. Bit znaku ma liczbę 1 w liczbie binarnej, oznacza to, że znak jest ujemny dla liczby, którą zachował. (tutaj liczba, o której mowa, to nie 2, ale uzupełnienie 2).
Ponieważ liczby są przechowywane jako uzupełnienie 2 (biorąc uzupełnienie jednego z liczby plus jeden), więc aby wyświetlić tę liczbę dwójkową
1111 1101
, w systemie dziesiętnym, najpierw musimy znaleźć uzupełnienie 2, które będzie:To jest uzupełnienie 2. Dziesiętna reprezentacja liczby binarnej
0000 0011
, to3
. A ponieważ bit znaku był jednym, jak wspomniano powyżej, więc odpowiedź jest następująca-3
.Wskazówka: Jeśli dokładnie zapoznasz się z tą procedurą, zauważysz, że wynikiem działania operatora dopełniacza jest liczba (operand - na którym ten operator jest stosowany) plus jeden ze znakiem ujemnym. Możesz spróbować również z innymi numerami.
źródło
add, flip, add
.0010
->0011
->1100
->1101
0010
1101
0010
NOT 0 = 1
iNOT 1 = 0
. W systemie czterobitowymNOT 0011
(3) =1100
(12 bez znaku, -4 podpis). Z tego, co rozumiem, uzupełnienie dwóch jest zdefiniowane jako(NOT n) + 1
i jest używane do znalezienia ujemnego odpowiednika liczby niezależnie od liczby bitów. Tak więc2c(5) = -5
. Widzisz, teraz ma to sens. Tak długo, jak nazywasz tę operację tym, co to jest: nieco NIE.int a = 4; System.out.println (~ a); Wynik byłby: -5
„~” dowolnej liczby całkowitej w java reprezentuje uzupełnienie 1 do liczby no. na przykład biorę ~ 4, co oznacza w reprezentacji binarnej 0100. po pierwsze, liczba całkowita wynosi cztery bajty, tj. 4 * 8 (8 bitów na 1 bajt) = 32. Więc w pamięci systemowej 4 jest reprezentowany jako 0000 0000 0000 0000 0000 0000 0000 0100 teraz ~ operator wykona uzupełnienie 1 na powyższym pliku binarnym
tzn. 1111 1111 1111 1111 1111 1111 1111 1011-> 1-to uzupełnienie najbardziej znaczący bit reprezentuje znak nie (albo - albo +), jeśli jest 1, to znak jest „-”, jeśli jest 0, to znak jest „+” zgodnie z ten nasz wynik jest liczbą ujemną, w java liczby ujemne są przechowywane w postaci uzupełnienia 2, uzyskany wynik musimy przekonwertować na uzupełnienie 2 (najpierw wykonaj uzupełnienie 1 i po prostu dodaj 1 do uzupełnienia 1). wszystkie one staną się zerami, z wyjątkiem najbardziej znaczącego bitu 1 (który jest naszym znakiem reprezentującym liczbę, co oznacza dla pozostałych 31 bitów 1111 1111 1111 1111 1111 1111 1111 1011 (uzyskany wynik ~ operatora) 1000 0000 0000 0000 0000 0000 0000 0100 (uzupełnienie 1)
1 (uzupełnienie 2)
1000 0000 0000 0000 0000 0000 0000 0101 teraz wynikiem jest -5 sprawdź ten link do wideo <[Bit mądrzy operatorzy w java] https://youtu.be/w4pJ4cGWe9Y
źródło
Po prostu ...........
Jako uzupełnienie 2 dowolnej liczby możemy obliczyć, odwracając wszystkie 1 na 0 i odwrotnie, niż dodajemy 1 do niego.
Tutaj N = ~ N daje wyniki - (N + 1) zawsze. Ponieważ system przechowuje dane w postaci uzupełnienia 2, co oznacza, że przechowuje ~ N w ten sposób.
Na przykład::
Teraz jest punkt, z którego pochodzi Minus. Moim zdaniem przypuszczamy, że mamy 32-bitowy rejestr, co oznacza, że 2 ^ 31 -1 bit jest zaangażowany w działanie, a reszta to jeden bit, który zmienia się we wcześniejszym obliczeniu (uzupełnieniu) przechowywany jako bit znaku, który zwykle wynosi 1. I otrzymujemy wynik jako ~ 10 = -11.
~ (-11) = 10;
Powyższe jest prawdą, jeśli printf ("% d", ~ 0); otrzymujemy wynik: -1;
Ale printf ("% u", ~ 0) niż wynik: 4294967295 na maszynie 32-bitowej.
źródło
Bitowy operator dopełniacza (~) jest jednostronny operatorem .
Działa zgodnie z następującymi metodami
Najpierw konwertuje podaną liczbę dziesiętną na odpowiadającą jej wartość binarną w przypadku 2 najpierw konwertuje 2 na 0000 0010 (na 8 bitową liczbę binarną).
Następnie konwertuje wszystkie 1 w liczbie na 0, a wszystkie zera na 1; wtedy liczba zmieni się na 1111 1101.
to reprezentuje uzupełnienie 2 dla -3.
Aby znaleźć wartość bez znaku za pomocą dopełniacza, tzn. Po prostu przekonwertować 1111 1101 na dziesiętne (= 4294967293), możemy po prostu użyć% u podczas drukowania.
źródło
Myślę, że dla większości ludzi zamieszanie wynika z różnicy między liczbą dziesiętną a liczbą binarną ze znakiem, więc wyjaśnijmy to najpierw:
dla ludzkiego świata dziesiętnego: 01 oznacza 1, -01 oznacza -1, dla świata binarnego komputera: 101 oznacza 5, jeśli jest niepodpisany. 101 oznacza (-4 + 1), jeśli jest podpisany, gdy podpisana cyfra znajduje się w pozycji x. | x
tak więc odwrócony bit 2 = ~ 2 = ~ (010) = 101 = -4 + 1 = -3 zamieszanie wynika z pomieszania podpisanego wyniku (101 = -3) i wyniku niestałego (101 = 5)
źródło
tl; dr
~
odwraca bity. W rezultacie znak się zmienia.~2
jest liczbą ujemną (0b..101
). Aby wydrukować liczbę ujemną,ruby
drukujemy-
uzupełnienie dwóch~2
:-(~~2 + 1) == -(2 + 1) == 3
. Liczby dodatnie są wyprowadzane bez zmian.Istnieje wartość wewnętrzna i jej reprezentacja ciągu. W przypadku liczb całkowitych dodatnich w zasadzie pokrywają się:
Ten ostatni jest równoważny z:
~
odwraca bity wartości wewnętrznej.2
jest0b010
.~2
jest0b..101
. Dwie kropki (..
) reprezentują nieskończoną liczbę znaków1
. Ponieważ najbardziej znaczący bit (MSB) wyniku jest1
, wynikiem jest liczba ujemna ((~2).negative? == true
). Aby wydrukować liczbę ujemną,ruby
drukowane jest-
następnie uzupełnienie dwóch wartości wewnętrznej. Uzupełnienie do dwóch oblicza się, odwracając bity, a następnie dodając1
. Uzupełnieniem dwóch0b..101
jest3
. Takie jak:Podsumowując, odwraca bity, co zmienia znak. Aby wydrukować liczbę ujemną, drukuje
-
, a następnie~~2 + 1
(~~2 == 2
).Powodem, dla którego
ruby
wyprowadza takie liczby ujemne, jest to, że traktuje przechowywaną wartość jako uzupełnienie wartości bezwzględnej do dwóch. Innymi słowy, przechowywane jest0b..101
. Jest to liczba ujemna i jako taka stanowi uzupełnienie pewnej wartości dwóchx
. Aby znaleźćx
, robi uzupełnienie dwóch0b..101
. Który jest uzupełnieniem dwóch uzupełnienia dwóchx
. Który jestx
(np~(~2 + 1) + 1 == 2
.).W przypadku zastosowania
~
liczby ujemnej, po prostu odwraca bity (co mimo to zmienia znak):Bardziej mylące jest to
~0xffffff00 != 0xff
(lub dowolna inna wartość z MSB równym1
). Załóżmy uprościć to trochę:~0xf0 != 0x0f
. To dlatego, że traktuje to0xf0
jako liczbę dodatnią. Co właściwie ma sens. Więc~0xf0 == 0x..f0f
. Wynik jest liczbą ujemną. Uzupełnieniem dwóch0x..f0f
jest0xf1
. Więc:Jeśli nie chcesz zastosować operatorów bitowych do wyniku, możesz rozważyć
~
jako-x - 1
operator:Ale jest to prawdopodobnie mało użyteczne.
Przykład Załóżmy, że masz 8-bitową (dla uproszczenia) maskę sieci i chcesz obliczyć liczbę
0
. Możesz je obliczyć, odwracając bity i wywołującbit_length
(0x0f.bit_length == 4
). Ale~0xf0 == 0x..f0f
musimy odciąć niepotrzebne fragmenty:Lub możesz użyć operatora XOR (
^
):źródło
Najpierw musimy podzielić daną cyfrę na cyfry binarne, a następnie odwrócić ją, dodając ostatnią cyfrę binarną. Po tym wykonaniu musimy podać znak przeciwny do poprzedniej cyfry, który jest zgodny ~ 2 = -3 Wyjaśnienie : Forma binarna 2s to 00000010 zmienia się na 11111101 to jest ich uzupełnienie, a następnie jest spełniona 00000010 + 1 = 00000011, która jest binarną formą trzech i -sign Tj, -3
źródło
Bit-mądry operator jest jednoargumentowym operatorem, który działa według metody znaku i wielkości, zgodnie z moim doświadczeniem i wiedzą.
Na przykład ~ 2 spowoduje -3.
Wynika to z faktu, że bitowy operator najpierw reprezentowałby liczbę w znaku i wielkość, która wynosi 0000 0010 (operator 8 bitów), gdzie MSB jest bitem znaku.
Później przyjmie liczbę ujemną 2, która wynosi -2.
-2 jest reprezentowane jako 1000 0010 (operator 8 bitów) w znaku i wielkości.
Później dodaje 1 do LSB (1000 0010 + 1), co daje 1000 0011.
Który wynosi -3.
źródło
JavaScript tylda (~) wymusza podaną wartość na uzupełnienie jednego - wszystkie bity są odwrócone. To wszystko, co robi tylda. To nie jest znak opiniowany. Nie dodaje ani nie odejmuje żadnej ilości.
Na standardowych procesorach komputerowych używających języków wysokiego poziomu, takich jak JavaScript, arytmetyka podpisana w BASE10 jest najczęstsza, ale należy pamiętać, że nie jest jedyna. Bity na poziomie procesora podlegają interpretacji na podstawie wielu czynników. Na poziomie „kodu”, w tym przypadku JavaScript, są one z definicji interpretowane jako 32-bitowa liczba całkowita ze znakiem (odejdźmy od tego). Pomyśl o tym jak o kwantowej, te 32 bity reprezentują wiele możliwych wartości naraz. Zależy to całkowicie od konwertowanego obiektywu, przez który patrzysz.
Wszystkie powyższe są prawdziwe jednocześnie.
źródło
Zasadniczo działanie jest uzupełnieniem, a nie negacją.
Tutaj x = ~ x daje wyniki - (x + 1) zawsze.
x = ~ 2
- (2 + 1)
-3
źródło