2012-11-23 17 views
11

Niedawno zrobiłem kurs języka Java (1 tydzień kursu zderzeniowego) i omówiliśmy niektóre matematykę binarną.Unary "~" operator - Co dokładnie się tutaj dzieje?

to jednoskładnikowa Operator ~ (tylda myślę, że to się nazywa?) Zostało wyjaśnione do nas tak:

To odwraca wzór bitowy obracając każde „0” na „1” i każdy „1” w " 0 ". np. Jest 8 bitów do bajtu. Jeśli masz następujący bajt: 00000000, odwrócona wartość zmieni się na 11111111.

Powyższe wyjaśnienie jest jasne i zwięzłe i całkowicie ma dla mnie sens. Dopóki to nie nastąpi, staram się to wdrożyć.

Biorąc pod uwagę to:

byte x = 3; 
byte y = 5; 
System.out.println(~x); 
System.out.println(~y); 

Wyjście jest:

-4 
-6 

Jestem bardzo mylić o tym, jak to się dzieje.

Jeśli +3 w binarnym to 11, to odwrócenie tego będzie wynosić 00, co oczywiście nie jest -3.

Ale ponieważ w bajcie jest 8 bitów, to czy binarna reprezentacja +3 nie powinna być zapisana jako 00000011?

Który odwróciłby się do 11111100. Przeliczony z powrotem na wartość dziesiętną byłby to 252. Jeśli jednak napiszesz +3 jako 011, to faktycznie konwertuje się na 100, czyli +4, ale jak Ty to robisz? wiesz, że to liczba ujemna?

Co powiesz, jeśli spróbujesz 0011, który przekształci się na 1100, a jeśli użyjesz pierwszego bitu jako znaku, to rzeczywiście stanie się -4.

Ah - więc w tym momencie myślałem, że gdzieś zmierzam.

Ale potem dostał się do drugiej wartości y = 5.

Jak napisać to? Używając tej samej logiki, +5 konwertuje na binarny 0101, który odwraca się do 1010.

I już teraz jestem okropnie zdezorientowany. Wygląda na to, że reprezentuje to wartość -2 lub niepodpisaną wartość dziesiętną +10? Żadne z nich nie jest drukowane -6.

Znowu, jeśli zwiększam długość do 8 cyfr bajtów, +5 to 00000101, który odwrócony staje się 11111010. I naprawdę nie mogę znaleźć sposobu, aby zmienić to na -6.

Czy ktoś tam to rozumie, ponieważ nie mam pojęcia, co się tutaj dzieje i im więcej numerów wydrukuję, tym bardziej jestem zdezorientowany.

Google nie wydaje się, aby wymyślić coś dużo na ten temat - może to nie podoba, patrząc na małe znaki operatora .. :-(

+2

Wszystkie wbudowane typy numeryczne w języku Java są * podpisane *. –

+2

@MarkoTopolnik char jest typem liczbowym i nie jest podpisany. –

+0

Po tych wszystkich bardzo pomocnych odpowiedziach dotyczących tego, czy jest to dopełnienie dwójki, znalazłem to wideo, które wydaje się wyjaśniać je całkiem dobrze. Dziękuję wszystkim, którzy odpowiedzieli. http://www.youtube.com/watch?v=Hof95YlLQk0&NR=1&feature=endscreen –

Odpowiedz

4

Z Wikipedii: W notacji uzupełniającej dwójki liczba nieujemna jest reprezentowana przez jej zwykłą reprezentację binarną; w tym przypadku najbardziej znaczącym bitem jest 0. Operacja uzupełniania dwójki jest operacją negacji, więc liczby ujemne są reprezentowane przez uzupełnienie dwójkowe wartości bezwzględnej.
Aby uzyskać uzupełnienie dwójkowe liczby binarnej, bity są odwrócone lub "odwrócone", za pomocą operacji bitowej NOT; wartość 1 jest następnie dodawana do wynikowej wartości, ignorując przepełnienie, które występuje, gdy bierze się dopełnienie dwóch z 0. http://en.wikipedia.org/wiki/Two%27s_complement

Więc jeśli masz 0101, który jest +5, odwrotność tego wynosi 1010, czyli -5 .

Tak naprawdę nie czytasz 010 jako 5, ale gdy zobaczysz 1 na początku, wiesz, że aby uzyskać numer, musisz ponownie odwrócić pozostałe cyfry, aby uzyskać dodatnią liczbę chcesz zanegować. Jeśli to ma sens.

To trochę obca koncepcja, jeśli wcześniej z nią nie pracowałeś. Z pewnością nie jest tak, że liczby dziesiętne działają, ale tak naprawdę jest to proste, gdy zobaczysz, co się dzieje.

Wartość 8 przecinku jest napisany jako 01010, który neguje do 10101. Pierwsza cyfra (1) oznacza, że ​​jest ujemna, a potem przerzucić resztę z powrotem, aby uzyskać wartość liczbową: 1010.

Jedna rzecz pamiętać, że uzupełnienie Dwójki nie jest tym samym, co zwykłe stare liczenie systemu binarnego. W normalnej wartości binarnej wartość 10101 (która w uzupełnieniu Two wynosi -8 jak wyżej) wynosi oczywiście 21. Domyślam się, że to jest miejsce, w którym pojawia się dezorientacja - jak rozpoznać różnicę, patrząc na nie? Musisz wiedzieć, która reprezentacja została użyta, aby zdecydować, jaka jest wartość tej liczby. Jest też dopełnienie One, które różni się nieco.

Podano tutaj dobry samouczek dotyczący obliczeń binarnych, w tym uzupełnienia jednego i drugiego. http://www.math.grin.edu/~rebelsky/Courses/152/97F/Readings/student-binary

+0

Och, widzę. Próbowałem odczytać je tak samo, jak liczby pozytywne, ale z 1 z przodu. Dziękuję za to. Również dla linków - są genialne. W końcu to rozumiem. Myślę. :-) –

+0

Chcę dodać, że wszystko dzieje się w 32-bitowych wartościach. Tak więc, kiedy powiedziałeś 3, był on w rzeczywistości binarny 00000000000000000000000000000011. Kiedy się odwróciłeś, staje się 11111111111111111111111111111100, co jest równoważne -4 w dwójkowym 32-bitowym uzupełnieniu. –

7

Zobacz prezentację: -

3 -> 0011 
~3 -> 1100 -> -4 (2's complement) 

5 -> 0101 
~5 -> 1010 -> -6 (2's complement) 

Ponieważ liczby całkowite ze znakiem są przechowywane jako dopełnienie 2, pobranie 2's complement z 1100 daje 4. Teraz, ponieważ 1100 jest liczbą ujemną.Tak więc wynikiem jest -4. Tak samo jest z 1010.

1100 
0011 - 1's complement 
0100 - 2's complement - value = 4 (take negative) 
+1

Dodatkowo zauważ, że operacja uzupełniania bitowego wykonuje jednoargumentową promocję numeryczną. –

+0

Uzupełnienie 2. Hmm. Nasz trener nie wspomniał o tym. Do Google idę. Dzięki. :-) –

2

Podawane liczby całkowite są prawie powszechnie przechowywane przy użyciu twos complement. Oznacza to odwrócenie bitów (pobranie uzupełnienia) i dodanie jednego. W ten sposób nie masz dwóch reprezentacji liczb całkowitych zero (+0 i -0), a niektóre podpisane operacje stają się łatwiejsze do wdrożenia w sprzęcie.

2

Java używa podpisanych cyfr w Two's complement. Twoje rozumowanie byłoby poprawne w C lub innych językach, gdy używasz typów jako "unsigned int" lub "unsigned char".