Warum liegt der Bytebereich in Java zwischen -128 und 127?


79

Ich verstehe nicht, warum der niedrigste Wert, den ein Byte annehmen kann, ist -128. Ich kann sehen, dass der höchste Wert ist 127, weil er 01111111binär ist, aber wie stellt man -128nur 8 Bits dar, von denen eines für das Vorzeichen verwendet wird? Positive 128 wären bereits 8-Bit, dh 10000000Sie benötigen ein 9. Bit, um das negative Vorzeichen darzustellen.

Könnte mir bitte jemand helfen, das zu erklären.



1
Es ist ähnlich wie bei den anderen Integer - Typen short, intund long.
Starblue

11
Eine bessere Frage ist why java byte type is not a range of 0..255? Tatsächlich stellen viele diese Frage, in den meisten Sprachen ist der byteTyp nicht signiert, aber auch in Java byteist er signiert, und ich (und viele andere) glaube, dass es ein schlechtes Design war, das vom ersten Tag an in Java verblieben ist. Es gibt Probleme, wenn Sie mit JNI arbeiten, und glauben Sie mir, wenn Sie etwas benennen, das byteSie wollen 0..255!
Amir Pashazadeh

Antworten:


92

Die Antwort ist die Ergänzung von zwei .

Kurz gesagt, Java (und die meisten modernen Sprachen) stellen keine vorzeichenbehafteten Ganzzahlen dar, die eine Darstellung mit vorzeichenbehafteter Größe verwenden. Mit anderen Worten, eine 8-Bit-Ganzzahl ist kein Vorzeichenbit, gefolgt von einer vorzeichenlosen 7-Bit-Ganzzahl.

Stattdessen werden negative Ganzzahlen in einem System dargestellt, das als Zweierkomplement bezeichnet wird. Dies ermöglicht eine einfachere arithmetische Verarbeitung in der Hardware und beseitigt auch die potenzielle Mehrdeutigkeit einer positiven Null und einer negativen Null. Ein Nebeneffekt der Eliminierung einer negativen Null besteht darin, dass am unteren Rand des Bereichs immer eine zusätzliche negative Zahl verfügbar ist.

Eine weitere interessante Eigenschaft von Zweierkomplementsystemen besteht darin, dass das erste Bit effektiv als Vorzeichenindikator fungiert (dh alle Zahlen, die mit Bit 1 beginnen, sind negativ), die nächsten sieben Bits jedoch nicht allein als vorzeichenlose Zahl für zu interpretieren sind welches das Vorzeichenbit angewendet wird.

Das Komplement von Two ist nicht sonderlich kompliziert, aber einen ersten guten Überblick darüber zu bekommen, was das Komplement von Two ist und wie und warum es funktioniert, würde wahrscheinlich den Rahmen einer SO-Antwort sprengen. Beginnen Sie mit dem Wikipedia-Artikel oder googeln Sie den Begriff für weitere Ressourcen.

Um zu versuchen, Ihre Anfrage zu -128 kurz zu beantworten, besteht die Grundidee beim Generieren einer Zweierkomplementzahl darin, die vorzeichenlose Form der Zahl anzunehmen, alle Bits zu invertieren und eins hinzuzufügen. 128 ohne Vorzeichen ist also 10000000. Invertiert ist es 01111111, und wenn Sie eins hinzufügen, erhalten Sie wieder 10000000. In einem Zweierkomplementsystem ist 10000000 eindeutig -128 und nicht +128. Zahlen größer oder gleich +128 können mit einem Zweierkomplementsystem einfach nicht in 8 Bits dargestellt werden, da sie mit den Formen negativer Zahlen nicht eindeutig wären.


Ordentlich! Mal sehen, ob ich es richtig verstanden habe: Stimmt es immer noch, dass 8-Bit-Zahlen, die mit 0 beginnen (außer 00000000), positiv und mit 1 beginnend negativ sind? Das einzig wirklich Knifflige am Zweierkomplement ist auch, dass die Bitdarstellung von Bytes nicht den gleichen Wert hat wie in einer Mathematikklasse, dh 10000000 ist normalerweise +128, aber als Byte ist es -128. Amirite?
Schlechte Anfrage

Du hast Recht. Das erste Bit ist genau dann 1, wenn die Zahl negativ ist. Wenn das erste Bit 0 ist, ist die Zahl entweder positiv oder Null.
Tyler McHenry

@ Tyler: Ich wette, Sie könnten meine Frage auch unter diesem Beitrag beantworten: stackoverflow.com/questions/16775169/… Ich hoffe, das ist nicht zu direkt, aber ich frage mich wirklich, und nach ein paar Monaten sporadischer Suche habe ich immer noch keine Hinweis: ~
JBA

Mit diesem Code-Byte b1 = 0b10000000; macht Kompilierungsfehler?
Zeds

30

Das Zweierkomplement funktioniert wie folgt;

Ein Byte besteht aus 8 Bits.

00000000 bedeutet 0

11111111 bedeutet 255

Wenn die Zahlen jedoch so dargestellt würden, würden wir nicht unterscheiden, ob die resultierende Zahl positiv oder negativ ist. Aus diesem Grund gibt uns das Bit auf der linken Seite diese Informationen. Wenn das Bit auf der linken Seite ist 0, können Sie den Wert anderer Bits oben auf hinzufügen zero. Wenn das Bit ist 1, sollten Sie oben auf hinzufügen -128. Weil das Bit auf der linken Seite zwei hoch sieben ist.

Beispiele;

In diesen Beispielen ist das Bit auf der linken Seite 1, dh wir addieren die Werte anderer Bits oben auf -128.

10000000 = -128 (-128 + 0)

10000001 = -127 (-128 + 1)

10000011 = -125 (-128 + 3)

10000111 = -121 (-128 + 7)

Gleiche Bits, aber diesmal ist das Bit links 0. Das heißt, wir fangen an, oben hinzuzufügen 0.

00000000 = 0 (0 + 0)

00000001 = 1 (0 + 1)

00000011 = 3 (0 + 3)

00000111 = 7 (0 + 7)

Wenn wir bis jetzt in Ordnung sind, die Antwort auf Ihre Frage,

die kleinstmögliche Anzahl

10000000 = -128

die größtmögliche Anzahl

011111111 = 127

Deshalb liegt der Bereich zwischen -128 und 127 .


8

Wie James in seinem Kommentar betonte, funktioniert das Zweierkomplement so.

Wenn wir es anders ausdrücken, können Sie 2 ^ 8 = 256 Arten von Werten darstellen. Dies wird in diesem Fall als 128 negative Zahlen, 127 positive Zahlen und Null verwendet. Wenn wir 7 Bits zur Darstellung des Werts verwenden würden, +1 Bit für ein Vorzeichen, könnten wir einen Wert weniger darstellen und hätten auch zwei Nullen (was sehr unglücklich wäre, da der Vergleich zweier Werte aus diesem Grund komplizierter wäre).


3

Grundlegende numerische Typen können 2 ^ n Zahlen darstellen. Schauen Sie sich einen Fall n = 2 an. Sie können vier Fälle darstellen, nennen wir sie a, b, c, d. Dann können Sie entweder zustimmen a=-2, b=-1, c=0, d=1(dies wird akzeptiert) oder a=-1, b=0, c=1, d=2(möglich, aber nicht verwendet). Also, wenn Sie nur eine Null und halten Sie 2 ^ n heißt Ihre abs(min) != maxErhöhung der nZüge die Grenzen, aber abs(min) != maxnoch hält.


3

Byte besteht aus 8 Bit ---> 1 Bit Vorzeichen (positiv oder negativ) 7 Bit Wert

also der Bereich -2 ^ 7 negativ (-128) bis 2 ^ 7 -1 positiv (127)


1

In Java werden alle Variablen wie Byte Short Int Long Float Double als Vorzeichen geschrieben. So ist es sehr einfach, dass das Kopfbit immer angibt, was ist (negativ oder positiv), aber da die Zahlen durch 2 teilbar sind, wird die Hälfte als negativ verschoben, 0 ist standardmäßig positiv. so sieht es also aus:

das ist positiv
+ | 0001001
1 | 0001001
das ist negativ
- | 0001001
0 | 0001001
als Byte kurz a negativ ist
-000000011111111
0000000011111111


0

Ohne auf das Zweierkomplement einzugehen: 2 ^ 8 (da ein Byte 8-stellig ist und 1 von 2 Werten haben kann) = 256, so dass die individuellsten Werte, die ein Byte darstellen kann, 256 sind. Die Darstellung der Zahlen -128 bis -1 ist also die Hälfte unserer Reichweite. Ich glaube, die Frage hier ist, warum der maximale positive Wert 127 statt 128 ist. Dies liegt daran, dass wir die Zahl 0 darstellen müssen, also sind 0-127 die anderen 128 Möglichkeiten unseres Bereichs.

Wenn wir nur positive Werte zulassen würden, z. B. ein vorzeichenloses Byte, bei dem negative Zahlen nicht möglich sind, wäre der Bereich 0-255, da dies 256 verschiedene Werte sind (einschließlich der 0).


0

Nachdem wir das Zweierkompliment der Zahl genommen hatten, gingen wir immer mit einem Zustand, der die Zahl extra darstellt, um diesen Zustand auf -128 zu setzen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.