JavaRush /Java-Blog /Random-DE /Bitweise Negation – warum ist das so?
Alex Bolgov
Level 37
Ташкент

Bitweise Negation – warum ist das so?

Veröffentlicht in der Gruppe Random-DE
Hallo zusammen :) Beim Lesen des Artikels „Bitweise Operationen“ hatte ich, wie einige andere auch, eine Frage: Warum erhalten wir, wenn wir die Zahl 342 invertieren, -343? So sieht es im Artikel aus: Bitweise Negation – warum so – 1Wer besonders neugierig ist (wie ich), hat eine Frage: „Hey, aber 010101001 ist kleiner als 101010110, es ist logisch, dass es kleiner als 342 und positiv sein sollte.“ Indem Sie es in einen beliebigen Online-Zahlenkonverter eingeben oder mit dem Code überprüfen:
Integer a = Integer.valueOf("010101001", 2);
System.out.println(Integer.toString(a, 10));
unerwartet bekommen wir etwas anderes als -343...
169
Oh, wie gut ist es, dass ich einmal in einem Kurs über Programmieren in C kurz etwas über die Vorzeichenziffer in ganzen Zahlen gehört habe. Nachdem ich eine Weile gegoogelt habe, kann ich nun erklären, um was für ein Tier es sich handelt. Bitweise Negation – warum so – 2Tatsächlich enthält der Artikel eine Ungenauigkeit, die verwirrend ist. Wenn wir mit dem Code überprüfen, was wirklich das Ergebnis der Invertierung der Zahl 342 ist:
int a = 342;
System.out.println(Integer.toBinaryString(~a));
dann werden wir ein etwas anderes Ergebnis sehen
11111111111111111111111010101001
Warum ist das so? Die Sache ist, dass eine Variable nicht einfach 101010110 enthalten kann; tatsächlich wird sie als gespeichert
000000000000000000000000101010110
Immerhin benötigt eine int-Variable 4 Bytes, d.h. 32 Bit – 32 Speicherzellen. Nach der Invertierung ändern sich absolut alle Zahlen, d.h. und „abgeschnittene“ führende Nullen. Jetzt kommt der spaßige Teil. Da in der Binärdarstellung das + oder – Vorzeichen vor einer Zahl nicht gespeichert werden kann, gibt es einen Trick: Das allererste Bit ist eigentlich für das Vorzeichen verantwortlich und ist genau das Vorzeichenbit . Und alle Zahlen werden nach dieser Logik gespeichert: Zahlen von 00...000 bis 01...111 sind positiv, beginnend bei 0 (also von 0 bis 2147483647) und beginnend von 10...000 bis 11...111 sind negativ, beginnend beim kleinsten und endend mit -1 (d. h. -2147483648 bis -1).
00000000000000000000000000000000 = 0
01111111111111111111111111111111 = 2147483647
10000000000000000000000000000000 = -2147483648
11111111111111111111111111111111 = -1
Und dann fragen Sie: „Okay, Nawalny, wir werden Ihnen glauben, aber warum haben Sie entschieden, dass dies sein Palast ist?“ Aber wie kommt es, dass es bei all dem -343 ist? Es ist wirklich einfach. Wir können dies einfach manuell berechnen. Wenn wir das allererste Bit aus der Binärversion der resultierenden Zahl 342 ( 1111111111111111111111111111111111111111010101001 ) „abschneiden“ (oder durch 0 ersetzen) und es wieder in die Dezimalform zurückführen.
String s = "01111111111111111111111010101001";
System.out.println(s + " = " + Integer.toString(Integer.valueOf(s, 2), 10));
dann verstehen wir das
01111111111111111111111010101001 = 2147483305
Tatsächlich haben wir hier am Anfang nicht einfach 1 „abgeschnitten“, sondern von dieser Zahl 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000. Was wir sehen werden:
~342 =
11111111111111111111111010101001 =
//в двоичном виде//
01111111111111111111111010101001 +
10000000000000000000000000000000
=
//в десятичном виде//
-2147483648 + 2147483305 = -343
Hier ist die benötigte Zahl -343 :) Leute, das ist mein erster Beitrag hier, bitte liken Sie ihn, wenn er Ihnen gefallen hat und er informativ war (ich möchte wirklich alle Erfolge sammeln 😄) Mehr zu diesem Thema können Sie hier lesen: Viel Glück an alle und vielen Dank für Ihre Aufmerksamkeit)
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION