Hoe worden gehele getallen intern weergegeven op bitniveau in Java?

Ik probeer te begrijpen hoe Java integer intern opslaat. Ik weet dat alle primitieve gehele getallen van Java zijn ondertekend (behalve kort?). Dat betekent dat er één bit minder beschikbaar is in een byte voor het getal.

Mijn vraag is, worden alle gehele getallen (positief en negatief) opgeslagen als twee-complement of zijn alleen negatieve getallen in twee-complement?

Ik zie dat in de specificaties x bit two's complement numberstaat. Maar ik raak vaak in de war.

Bijvoorbeeld:

 int x = 15; // Stored as binary as is?  00000000 00000000 00000000 00001111?
  int y = -22; // Stored as two complemented value? 11111111 11111111 11111111 11101010

Bewerken

Voor alle duidelijkheid: x = 15

  In binary as is: `00000000 00000000 00000000 00001111'
  Two's complement: `11111111 11111111 11111111 11110001`

Dus als uw antwoord all-getallen is, worden opgeslagen als twee-complement, dan:

 int x = 15; // 11111111 11111111 11111111 11110001
  int y = -22 // 11111111 11111111 11111111 11101010

De verwarring hier is weer dat het bord zegt, beide zijn negatieve getallen. Misschien lees ik het verkeerd / begrijp ik het verkeerd?

Bewerken
Ik weet niet zeker of mijn vraag verwarrend is. Gedwongen om de vraag te isoleren:

Mijn vraag precies: worden positieve getallen opgeslagen in binary as isterwijl negatieve getallen worden opgeslagen als two's complement?

Sommigen zeiden dat alles wordt opgeslagen in het complement van twee en één antwoord zegt dat alleen negatieve getallen worden opgeslagen als complement van twee.


Antwoord 1, autoriteit 100%

Laten we beginnen met een samenvatting van de primitieve gegevenstypen van Java:

byte: het gegevenstype byte is een 8-bits geheel getal van twee-complement met teken.

Kort: het gegevenstype Kort is een 16-bits geheel getal met een teken van twee complementen.

int:Int-gegevenstype is een 32-bits, ondertekend twee-complement geheel getal.

long:Long-gegevenstype is een 64-bits ondertekend twee-complement integer.

float:Float-gegevenstype is een 32-bits IEEE 754 zwevende komma met enkele precisie.

dubbel: dubbel gegevenstype is een 64-bits IEEE 754 drijvende komma met dubbele precisie.

boolean:het booleaanse gegevenstype vertegenwoordigt één stukje informatie.

char:char-gegevenstype is een enkel 16-bits Unicode-teken.

Bron

Twee complement

“Het goede voorbeeld is van wikidat de relatie met het complement van twee wordt gerealiseerd door op te merken dat 256 = 255 + 1, en (255 − x) het enen-complement van x is

0000 0111=7 twee complement is 1111 1001= -7

de manier waarop het werkt is dat de MSB (de meest significante bit) een negatieve waarde krijgt, dus in het bovenstaande geval

-7 = 1001= -8 + 0+ 0+ 1

Positieve gehele getallen worden over het algemeen opgeslagen als eenvoudige binaire getallen (1 is 1, 10 is 2, 11 is 3, enzovoort).

Negatieve gehele getallen worden opgeslagen als het complement van hun absolute waarde. Het twee-complement van een positief getal is bij gebruik van deze notatie een negatief getal.

Bron

Omdat ik een paar punten voor dit antwoord heb gekregen, heb ik besloten er meer informatie aan toe te voegen.

Een meer gedetailleerd antwoord:

Er zijn onder andere vier hoofdbenaderingen om positieve en negatieve getallen in binair weer te geven, namelijk:

  1. Getekende Magnitude
  2. Iemands Complement
  3. Twee’s Complement
  4. Vooroordeel

1. Ondertekende Magnitude

Gebruikt de meest significante bit om het teken weer te geven, de overige bits worden gebruikt om de absolute waarde weer te geven. Waar 0staat voor een positief getalen 1staat voor een negatief getal, bijvoorbeeld:

1011 = -3
0011 = +3

Deze weergave is eenvoudiger. U kunt echter geen binaire getallen toevoegen op dezelfde manier als decimale getallen, waardoor het moeilijker wordt om deze op hardwareniveau te implementeren. Bovendien gebruikt deze benadering twee binaire patronen om de 0, -0 (1000)en +0 (0000)weer te geven.

2. Iemands aanvulling

In deze weergave keren we alle bits van een bepaald getal om om de complementaire waarde ervan te achterhalen. Bijvoorbeeld:

010 = 2, so -2 = 101 (inverting all bits).

Het probleem met deze weergave is dat er nog steeds twee bitpatronen bestaan ​​om de 0, negatieve 0 (1111)en positieve 0 (0000)

weer te geven

3. Twee’s complement

Om het negatief van een getal te vinden, in deze representatie, keren we alle bits om en voegen dan één bit toe. Het toevoegen van één bit lost het probleem op van het hebben van twee bits-patronen die 0 vertegenwoordigen. In deze representatie hebben we slechts één patroon voor
0 (0000).

We willen bijvoorbeeld de binaire negatieve representatie van 4 (decimaal) vinden met behulp van 4 bits. Eerst converteren we 4 naar binair:

4 = 0100

dan keren we alle bits om

0100 -> 1011

Tot slot voegen we een bit toe

1011 + 1 = 1100.

Dus 1100 is gelijk aan -4 in decimaal als we een twee-complement binaire representatie met 4 bits gebruiken.

Een snellere manier om de complementaire waarde te vinden, is door het eerste bit als waarde 1 te fixeren en de resterende bits te inverteren. In het bovenstaande voorbeeld zou het zoiets zijn als:

0100 -> 1100
^^ 
||-(fixing this value)
|--(inverting this one)

Two’s Complement-representatie, behalve dat het slechts één representatie voor 0 heeft, voegt het ook twee binaire waarden toe op dezelfde manier als in decimale, even getallen met verschillende tekens. Desalniettemin is het noodzakelijk om te controleren op overloopgevallen.

4. Bias

Deze weergave wordt gebruikt om de exponent in de IEEE 754-norm voor zwevende punten weer te geven. Het heeft het voordeel dat de binaire waarde met alle bits op nul de kleinste waarde vertegenwoordigt. En de binaire waarde met alle bits tot 1 vertegenwoordigt de grootste waarde. Zoals de naam aangeeft, is de waarde gecodeerd (positief of negatief) in binair met n bits met een bias (normaal 2^(n-1) of 2^(n-1)-1).

Dus als we 8 bits gebruiken, wordt de waarde 1 in decimaal weergegeven in binair met een bias van 2^(n-1), door de waarde:

+1 + bias = +1 + 2^(8-1) = 1 + 128 = 129
converting to binary
1000 0001

Antwoord 2, autoriteit 56%

Java integers zijn 32 bits en altijd ondertekend. Dit betekent dat de meest significante bit (MSB) werkt als de tekenbit. Het geheel getal dat wordt vertegenwoordigd door een intis niets anders dan de gewogen som van de bits. De gewichten worden als volgt toegekend:

Bit#    Weight
31      -2^31
30       2^30
29       2^29
...      ...
2        2^2
1        2^1
0        2^0

Merk op dat het gewicht van de MSB negatief is (de grootst mogelijke negatieve eigenlijk), dus als deze bit aan staat, wordt het hele getal (de gewogen som) negatief.

Laten we het simuleren met 4-bits getallen:

Binary    Weighted sum            Integer value
0000       0 + 0 + 0 + 0           0
0001       0 + 0 + 0 + 2^0         1
0010       0 + 0 + 2^1 + 0         2
0011       0 + 0 + 2^1 + 2^0       3
0100       0 + 2^2 + 0 + 0         4
0101       0 + 2^2 + 0 + 2^0       5
0110       0 + 2^2 + 2^1 + 0       6
0111       0 + 2^2 + 2^1 + 2^0     7 -> the most positive value
1000      -2^3 + 0 + 0 + 0        -8 -> the most negative value
1001      -2^3 + 0 + 0 + 2^0      -7
1010      -2^3 + 0 + 2^1 + 0      -6
1011      -2^3 + 0 + 2^1 + 2^0    -5
1100      -2^3 + 2^2 + 0 + 0      -4
1101      -2^3 + 2^2 + 0 + 2^0    -3
1110      -2^3 + 2^2 + 2^1 + 0    -2
1111      -2^3 + 2^2 + 2^1 + 2^0  -1

Dus het complement van de twee is geen exclusief schema voor het representeren van negatieve gehele getallen, we kunnen eerder zeggen dat de binaire representatie van gehele getallen altijd hetzelfde is, we negeren alleen het gewicht van het meest significante bit. En dat bit bepaalt het teken van het gehele getal.

In C is er een trefwoord unsigned(niet beschikbaar in java), dat kan worden gebruikt voor het declareren van unsigned int x;. In de gehele getallen zonder teken is het gewicht van de MSB positief (2^31) in plaats van negatief. In dat geval is het bereik van een unsigned int0tot 2^32 - 1, terwijl een intbereik -2^31tot 2^31 - 1.

Vanuit een ander gezichtspunt, als je de twee complement van xbeschouwt als ~x + 1(NIET x plus één), dan is hier de uitleg:

Voor elke xis ~xgewoon de bitsgewijze inverse van x, dus overal waar xeen 1-bit, ~xzal daar een 0-bit hebben (en vice versa). Dus als je deze bij elkaar optelt, is er geen carry in de optelling en is de som gewoon een geheel getal waarvan elke bit 1is.

Voor 32-bits gehele getallen:

x + ~x = 1111 1111 1111 1111 1111 1111 1111 1111
x + ~x + 1 =   1111 1111 1111 1111 1111 1111 1111 1111 + 1
           = 1 0000 0000 0000 0000 0000 0000 0000 0000

De meest linkse 1-bit wordt gewoon weggegooid, omdat deze niet in 32-bits past (integer overflow). Dus,

x + ~x + 1 = 0
-x = ~x + 1

Je kunt dus zien dat de negatieve xkan worden weergegeven door ~x + 1, wat we het twee-complement van xnoemen.


Antwoord 3, autoriteit 9%

Ik heb het volgende programma uitgevoerd om het te weten

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));
    }
}

Uitvoer is

1010
11111111111111111111111111110110

Uit de uitvoer lijkt het erop dat het twee-complement heeft gebruikt.


Antwoord 4, autoriteit 5%

Oracle biedt enige documentatie over Java Datatypesdie u mogelijk interessant vinden. Specifiek:

int: Het gegevenstype int is een 32-bits geheel getal met twee complementen. Het heeft een minimumwaarde van -2.147.483.648 en een maximumwaarde van 2.147.483.647 (inclusief).

Trouwens, kort wordt ook opgeslagen als complement van twee.


Antwoord 5, autoriteit 4%

Positieve nummers worden opgeslagen/opgevraagd zoals ze zijn.

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. 

Maar negatieve getallen worden opgeslagen na het complement van 2 (anders dan
MSB bit), en MSB bit wordt ingesteld op 1.

b.g) bij het opslaan van -10 dan

 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

Bij het ophalen bleek dat MSB op 1. is ingesteld, dus het is negatief nr.
En 2’s aanvulling zal anders worden uitgevoerd dan MSB.

 1-111 1110  --> 1-000 0001 + 1 --> 1-000 0010
  Since MSB representing this is negative 10 --> hence  -10 will be retrived.

Gieten

Merk ook op dat wanneer u int / korte tot byte giet, slechts laatste byte wordt overwogen, samen met LAATSTE BYTE MSB,

Neem voorbeeld “-130” kort, het kan worden opgeslagen zoals hieronder

(MSB)1-(2's complement of)130(1000 0010) --> 1-111 1111 0111 1110

Nu byte casting duurde de laatste byte die 0111 1110 is. (0-MSB)
Aangezien MSB zegt dat het + VE-waarde is, zodat het wordt genomen zoals het is.
Dat is 126. (+ ve).

Nog een ander voorbeeld “130” kort, het kan worden opgeslagen zoals hieronder

 0-000 000 1000 0010     (MSB = 0)

Nu bytegieten duurde de laatste byte die 1000 0010 is. (1 = MSB)
Aangezien MSB zegt dat het een waarde is, wordt de aanvulling van 2 uitgevoerd en wordt het negatieve getal geretourneerd. Dus in dit geval zal -126 worden geretourneerd.

1-000 0010  -> (1's complement) -> 1-111 1101 
             -> (2's complement) 1-111 1101 + 1 -> 1-111 1110 -> (-)111 1110
               = -126

diff tussen (int) (char) (byte) -1 en (int) (kort) (byte) -1

(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) 

Evenzo

(short)(byte)-1-> 1-111 1111 1111 1111  (sign bit is carry forwarded on left) 

Maar

(int)(char)(byte)-1 -> 0-0000000 00000000 11111111 11111111  = 65535
since char is unsigned; MSB won't be carry forwarded. 

en

(int)(Short)(byte)-1 -> 1-1111111 11111111 11111111 11111111 = -1
since short is signed; MSB is be carry forwarded. 

referenties

Waarom is de aanvulling van twee gebruikte om negatieve nummers te vertegenwoordigen?

Wat is “2’s complement”?


Antwoord 6, Autoriteit 3%

Het belangrijkste bit (32nd) geeft aan dat het aantal positief of negatief is. Als het 0 is, betekent dit dat het nummer positief is en het wordt opgeslagen in zijn werkelijke binaire weergave. Maar als het 1 is, betekent dit dat het nummer negatief is en wordt opgeslagen in de aanvullende weergave van de twee. Dus wanneer we gewicht -2 ^ 32 geven aan het 32e bit, terwijl we de gehele waarde van zijn binaire weergave herstellen, krijgen we het eigenlijke antwoord.


Antwoord 7, Autoriteit 3%

Volgens Dit document zijn alle gehele getallen ondertekend en opgeslagen in het complementformaat van twee voor Java. Niet zeker van zijn betrouwbaarheid ..


Antwoord 8, Autoriteit 2%

Positieve nummers worden rechtstreeks opgeslagen als binair. 2’s compliment is vereist voor negatieve getallen.

Bijvoorbeeld:

15: 00000000 00000000 00000000 00001111
-15: 11111111 11111111 11111111 11110001

Hier is het verschil in getekend bit.


Antwoord 9, autoriteit 2%

Bedankt, dreamcrashvoor het antwoord https://stackoverflow.com/a/13422442/1065835 ; op de wikipaginageven ze een voorbeeld dat me hielp begrijpen hoe ik ontdek de binaire representatie van de negatieve tegenhanger van een positief getal.

Bij gebruik van 1 byte (= 2 nibbles = 8 bits), het decimale getal 5
wordt vertegenwoordigd door

0000 01012 De meest significante bit is 0, dus het patroon vertegenwoordigt a
niet-negatieve waarde. Om te converteren naar −5 in twee-complement notatie, de
bits worden omgekeerd; 0 wordt 1, en 1 wordt 0:

1111 1010 Op dit punt is het cijfer het enen-complement van de
decimale waarde −5. Om het complement van de twee te verkrijgen, wordt 1 toegevoegd aan de
resultaat, geven:

1111 1011 Het resultaat is een ondertekend binair getal dat de . vertegenwoordigt
decimale waarde −5 in twee-complementvorm. Het belangrijkste is:
1, dus de weergegeven waarde is negatief.


Antwoord 10

Voor positief geheel getal is 2’complementwaarde hetzelfde met MSB bit 0 (like +14 2'complement is 01110).

Alleen voor een negatief geheel getal berekenen we de 2’complementwaarde (-14= 10001+1 = 10010).

Dus het laatste antwoord is dat beide waarden(+ve and -ve)alleen in 2’complementvorm worden opgeslagen.

Other episodes