Zacznijmy od podsumowania prymitywnych typów danych Java:
bajt : typ danych Byte to 8-bitowa liczba całkowita uzupełniająca do dwóch ze znakiem .
Krótki : Krótki typ danych to 16-bitowa liczba całkowita uzupełniająca do dwóch ze znakiem .
int: Int to 32-bitowa liczba całkowita z dopełnieniem do dwóch ze znakiem .
long: typ danych Long to 64-bitowa liczba całkowita z dopełnieniem do dwóch ze znakiem .
float: typ danych Float to 32-bitowy zmiennoprzecinkowy IEEE 754 o pojedynczej precyzji .
double : double typ danych to 64-bitowy zmiennoprzecinkowy podwójnej precyzji IEEE 754 .
boolean: boolean typ danych reprezentuje jeden bit informacji .
char: char typ danych to pojedynczy 16-bitowy znak Unicode .
Źródło
Uzupełnienie dwóch
„Dobrym przykładem jest wiki, że związek z dopełnieniem do dwóch jest realizowany poprzez odnotowanie, że 256 = 255 + 1, a (255 - x) jest uzupełnieniem x
0000 0111 = 7 dopełnienia do dwóch to 1111 1001 = -7
działa to tak, że MSB (najbardziej znaczący bit) otrzymuje wartość ujemną, więc w powyższym przypadku
-7 = 1001 = -8 + 0+ 0+ 1
Dodatnie liczby całkowite są zwykle przechowywane jako proste liczby binarne (1 to 1, 10 to 2, 11 to 3 itd.).
Ujemne liczby całkowite są przechowywane jako uzupełnienie do dwóch wartości bezwzględnych. Uzupełnienie do dwóch liczby dodatniej jest w przypadku użycia tego zapisu jako liczby ujemnej.
Źródło
Ponieważ otrzymałem kilka punktów za tę odpowiedź, postanowiłem dodać do niej więcej informacji.
Bardziej szczegółowa odpowiedź:
Między innymi istnieją cztery główne podejścia do przedstawiania liczb dodatnich i ujemnych w systemie dwójkowym, a mianowicie:
- Podpisana wielkość
- Dopełnienie
- Dopełnienie do dwóch
- Stronniczość
1. Podpisana wielkość
Używa najbardziej znaczącego bitu do reprezentowania znaku, pozostałe bity są używane do reprezentowania wartości bezwzględnej. Gdzie 0 oznacza liczbę dodatnią, a 1 oznacza liczbę ujemną , na przykład:
1011 = -3
0011 = +3
Ta reprezentacja jest prostsza. Jednak nie można dodawać liczb binarnych w taki sam sposób, jak dodaje się liczby dziesiętne, co utrudnia implementację na poziomie sprzętu. Co więcej, to podejście wykorzystuje dwa wzorce binarne do reprezentowania 0, -0 (1000) i +0 (0000) .
2. Uzupełnienie
W tej reprezentacji odwracamy wszystkie bity danej liczby, aby znaleźć jej komplementarność. Na przykład:
010 = 2, so -2 = 101 (inverting all bits).
Problem z tą reprezentacją polega na tym, że nadal istnieją dwa wzorce bitowe reprezentujące 0, ujemne 0 (1000) i dodatnie 0 (0000)
3. Dopełnienie do dwóch
Aby znaleźć minus liczby, w tej reprezentacji odwracamy wszystkie bity, a następnie dodajemy jeden bit. Dodanie jednego bitu rozwiązuje problem posiadania dwóch wzorców bitowych reprezentujących 0. W tej reprezentacji mamy tylko jeden wzorzec dla
0 (0000) .
Na przykład, chcemy znaleźć binarną ujemną reprezentację 4 (dziesiętnie) za pomocą 4 bitów. Najpierw zamieniamy 4 na binarne:
4 = 0100
następnie odwracamy wszystkie bity
0100 -> 1011
na koniec dodajemy trochę
1011 + 1 = 1100.
Więc 1100 jest równoważne -4 dziesiętnie, jeśli używamy binarnej reprezentacji dopełnienia Two z 4 bitami.
Szybszym sposobem znalezienia komplementarnego jest ustalenie pierwszego bitu o wartości 1 i odwrócenie pozostałych bitów. W powyższym przykładzie byłoby to coś takiego:
0100 -> 1100
^^
||-(fixing this value)
|--(inverting this one)
Reprezentacja dopełnienia do dwóch, oprócz posiadania tylko jednej reprezentacji dla 0, dodaje również dwie wartości binarne w taki sam sposób, jak w liczbach dziesiętnych, parzystych z różnymi znakami. Niemniej jednak konieczne jest sprawdzenie przypadków przepełnienia.
4. Odchylenie
Ta reprezentacja jest używana do reprezentowania wykładnika w normie IEEE 754 dla zmiennoprzecinkowych. Ma tę zaletę, że wartość binarna ze wszystkimi bitami do zera reprezentuje najmniejszą wartość. A wartość binarna ze wszystkimi bitami do 1 reprezentuje największą wartość. Jak sama nazwa wskazuje, wartość jest kodowana (dodatnio lub ujemnie) binarnie z n bitami z odchyleniem (zwykle 2 ^ (n-1) lub 2 ^ (n-1) -1).
Więc jeśli używamy 8 bitów, wartość 1 w systemie dziesiętnym jest reprezentowana binarnie z odchyleniem 2 ^ (n-1), przez wartość:
+1 + bias = +1 + 2^(8-1) = 1 + 128 = 129
converting to binary
1000 0001
binary as is
podczas gdy -ve liczby są przechowywane wtwo's complement
?Uruchomiłem następujący program, aby to wiedzieć
public class Negative { public static void main(String[] args) { int i =10; int j = -10; System.out.println(Integer.toBinaryString(i)); System.out.println(Integer.toBinaryString(j)); } }
Wyjście jest
1010 11111111111111111111111111110110
Z wyników wynika, że posługiwał się dopełnieniem do dwóch.
źródło
11111111 11111111 11111111 11110110
. Twoje wypisuje się, podczas gdy binarny dla 10 to 1010. Czyli tylko -ve liczby są przechowywane jako uzupełnienia do dwóch?Oracle udostępnia dokumentację dotyczącą typów danych Java, która może okazać się interesująca. Konkretnie:
Przy okazji, short jest również przechowywane jako uzupełnienie do dwóch.
źródło
e.g) For +ve number 10; byte representation will be like 0-000 0010 (0 - MSB will represent that it is +ve). So while retrieving based on MSB; it says it is +ve, so the value will be taken as it is.
np. podczas przechowywania -10 wtedy
0-000 0010 -> (1's complement) -> 0-111 1101 -> (2's complement) 0-111 1101 + 1 -> 0-111 1110 Now MSB will be set to one, since it is negative no -> 1-111 1110
podczas pobierania okazało się, że MSB jest ustawione na 1. Więc jest to minus nie. Uzupełnienie 2 zostanie wykonane inaczej niż MSB.
1-111 1110 --> 1-000 0001 + 1 --> 1-000 0010 Since MSB representing this is negative 10 --> hence -10 will be retrived.
Należy również pamiętać, że podczas rzutowania int / short do bajtu, tylko ostatni bajt będzie brany pod uwagę wraz z ostatnim bajtem MSB,
Weźmy przykład „-130” w skrócie, może być przechowywany jak poniżej
(MSB)1-(2's complement of)130(1000 0010) --> 1-111 1111 0111 1110
Teraz rzutowanie bajtów zajęło ostatni bajt, czyli 0111 1110. (0-MSB) Ponieważ MSB mówi, że jest to wartość + ve, zostanie przyjęty taki, jaki jest. To jest 126. (+ ve).
Weź inny przykład „130” w skrócie, może być przechowywany jak poniżej
0-000 000 1000 0010 (MSB = 0)
Teraz rzutowanie bajtów zajęło ostatni bajt, czyli 1000 0010. (1 = MSB) Ponieważ MSB mówi, że jest to wartość -ve, zostanie wykonane uzupełnienie 2 i zostanie zwrócona liczba ujemna. Więc w tym przypadku -126 zostanie zwrócone.
1-000 0010 -> (1's complement) -> 1-111 1101 -> (2's complement) 1-111 1101 + 1 -> 1-111 1110 -> (-)111 1110 = -126
(byte)-1 -> 0-000 0001 (2's Comp) -> 0-111 1111 (add sign) -> 1-111 1111 (char)(byte)-1 -> 1-111 1111 1111 1111 (sign bit is carry forwarded on left)
podobnie
(short)(byte)-1-> 1-111 1111 1111 1111 (sign bit is carry forwarded on left)
Ale
(int)(char)(byte)-1 -> 0-0000000 00000000 11111111 11111111 = 65535 since char is unsigned; MSB won't be carry forwarded.
I
(int)(Short)(byte)-1 -> 1-1111111 11111111 11111111 11111111 = -1 since short is signed; MSB is be carry forwarded.
Dlaczego uzupełnienie do dwóch jest używane do reprezentowania liczb ujemnych?
Co to jest „Uzupełnienie 2”?
źródło
Najbardziej znaczący bit (32.) wskazuje, że liczba jest dodatnia lub ujemna. Jeśli wynosi 0, oznacza to, że liczba jest dodatnia i jest przechowywana w rzeczywistej reprezentacji binarnej. ale jeśli jest 1, oznacza to, że liczba jest ujemna i jest przechowywana w reprezentacji dopełnienia do dwóch. Kiedy więc przypisujemy wagę -2 ^ 32 do 32-go bitu, jednocześnie przywracając wartość całkowitą z jego reprezentacji binarnej, otrzymujemy rzeczywistą odpowiedź.
źródło
Zgodnie z tym dokumentem wszystkie liczby całkowite są podpisywane i przechowywane w formacie dopełnienia do dwóch dla języka Java. Nie jestem pewien co do jego niezawodności.
źródło
liczby dodatnie są przechowywane bezpośrednio jako binarne. Komplement 2 jest wymagany dla liczb ujemnych.
na przykład:
15: 00000000 00000000 00000000 00001111-15
: 11111111 11111111 11111111 11110001
tutaj jest różnica w bitach ze znakiem.
źródło
Dziękuję, dreamcrash za odpowiedź https://stackoverflow.com/a/13422442/1065835 ; na stronie wiki podają przykład, który pomógł mi zrozumieć, jak znaleźć binarną reprezentację ujemnego odpowiednika liczby dodatniej.
źródło
Dla dodatniej liczby całkowitej 2 'wartość uzupełnienia jest taka sama, jak bit 0 MSB
(like +14 2'complement is 01110)
.Dla tylko ujemnych liczb całkowitych obliczamy wartość uzupełnienia 2 '
(-14= 10001+1 = 10010)
.Tak więc ostateczna odpowiedź brzmi: obie wartości
(+ve and -ve)
są przechowywane tylko w postaci uzupełnienia 2 '.źródło