Warum wird Hexadezimalzahlen mit 0x vorangestellt?

414

Warum werden Hexadezimalzahlen vorangestellt 0x? Ich verstehe die Verwendung des Präfixes, aber ich verstehe nicht, welche Bedeutung es hat, warum 0xgewählt wurde.

unj2
quelle
9
Jetzt merke ich, dass der Titel und der Text zwei völlig unterschiedliche Fragen stellen. Die meisten Antworten konzentrieren sich auf die Frage im Titel. Die Antwort auf die Frage im Text lautet einfach "es hat nichts zu bedeuten - es ist lediglich ein Präfix, das dem Compiler mitteilt, dass die Ganzzahl hexadezimal geschrieben ist".
Andreas Rejbrand
30
Um pedantisch zu sein, könnte man die Frage im Titel auch auf zwei verschiedene Arten interpretieren: 1) "Warum werden Hexadezimalzahlen im Gegensatz zu anderen Präfixen oder Indikatoren als 0x vorangestellt?" 2) "Warum müssen wir bei der Eingabe von Hexadezimalzahlen ein Präfix verwenden? Sicher erkennt der Compiler 58A auch ohne das Präfix als Hexadezimalzahl?" Die Antwort auf die zweite Interpretation der Frage ist trivial. "123" ist auch eine Hexadezimalzahl.
Andreas Rejbrand

Antworten:

440

Kurzgeschichte: Der 0erzählt dem Parser, dass es sich um eine Konstante handelt (und nicht um eine Kennung / ein reserviertes Wort). Es ist noch etwas erforderlich, um die Zahlenbasis anzugeben: Das xist eine willkürliche Wahl.

Lange Geschichte: In den 60er Jahren waren die vorherrschenden Programmiernummernsysteme dezimal und oktal - Mainframes hatten 12, 24 oder 36 Bit pro Byte, was durch 3 = log2 (8) gut teilbar ist.

Die BCPL-Sprache verwendete die Syntax 8 1234für Oktalzahlen. Als Ken Thompson B aus BCPL erstellte, verwendete er 0stattdessen das Präfix. Das ist toll, weil

  1. Eine Ganzzahlkonstante besteht jetzt immer aus einem einzelnen Token.
  2. Der Parser kann immer noch sofort erkennen, dass er eine Konstante hat.
  3. Der Parser kann die Basis sofort erkennen ( 0ist in beiden Basen gleich).
  4. es ist mathematisch vernünftig ( 00005 == 05) und
  5. Es werden keine wertvollen Sonderzeichen benötigt (wie in #123).

Als C aus B erstellt wurde, entstand der Bedarf an Hexadezimalzahlen (der PDP-11 hatte 16-Bit-Wörter) und alle oben genannten Punkte waren noch gültig. Da für andere Maschinen noch Oktale benötigt wurden, 0xwurde diese willkürlich gewählt ( 00wurde wohl als umständlich ausgeschlossen).

C # ist ein Nachkomme von C und erbt daher die Syntax.

Řrřola
quelle
112
Ich glaube nicht 0xüber 00war Präferenz / Ungeschicklichkeit. 00würde vorhandenen Code brechen. 0010wie oktal ist 8, während 0010wie hexidezimal wäre 16. Sie konnten keine Zahl als Indikator für eine zweite Ziffer verwenden (außer 8oder 9und haben auch keine hexadezimale Bedeutung), daher ist ein Buchstabe ein Muss. Und das lässt entweder 0hoder 0x( H e X idecimal). Von diesem Punkt an scheint es wirklich wieder die Präferenz zu sein.
GManNickG
23
Die Verwendung eines 0Präfixes für Oktal hat im Laufe der Jahre so viele Probleme verursacht. Insbesondere in Ländern wie Großbritannien, in denen Telefonnummern mit a beginnen 0. Javascript und viele andere Sprachen würden diese als oktal analysieren und die Zahl vor dem Speichern entstellen. Um den Spaß zu steigern, würde ein beliebtes Datenbankprodukt stillschweigend zur Dezimalanalyse zurückkehren, wenn die Zahl ein 8oder enthält 9.
Basic
1
12, 24 und 36 sind auch durch 4 teilbar. Warum haben sie dafür nicht an Hexadezimal gedacht?
Phuclv
4
@ LưuVĩnhPhúc Wahrscheinlich, weil hexadezimal nicht sehr relevant war. Die meiste Hardware, Software und Dokumentation der Zeit passt viel besser oktal. BCPL wurde zuerst auf einem 36-Bit-IBM 7094 implementiert , wobei das Befehlsformat in zwei 3-Bit-Teile und zwei 15-Bit-Teile aufgeteilt war. 6 Bit Zeichen; und Dokumentation in Oktal. Die frühen Implementierungen von B waren auf einem PDP-7 (18 Bit) und einem Honeywell GE-945 (36 Bit, jedoch mit 18 Bit Adressierung und Unterstützung für 6 und 9 Bit Bytes). Der 16-Bit-PDP-11 kam nach B heraus, hätte also das Design von B nicht wesentlich beeinflusst.
8bittree
97

Hinweis: Ich kenne die richtige Antwort nicht, aber das Folgende ist nur meine persönliche Spekulation!

Wie bereits erwähnt, bedeutet eine 0 vor einer Zahl, dass sie oktal ist:

04524 // octal, leading 0

Stellen Sie sich vor, Sie müssten ein System zur Bezeichnung von Hexadezimalzahlen entwickeln und beachten, dass wir in einer Umgebung im C-Stil arbeiten. Wie wäre es mit einer Montage? Leider können Sie nicht - es würde Ihnen ermöglichen, Token zu erstellen, die gültige Bezeichner sind (z. B. Sie könnten eine Variable gleich benennen), was zu einigen bösen Zweideutigkeiten führen würde.

8000h // hex
FF00h // oops - valid identifier!  Hex or a variable or type named FF00h?

Sie können aus demselben Grund nicht mit einem Charakter führen:

xFF00 // also valid identifier

Die Verwendung eines Hashs wurde wahrscheinlich verworfen, weil er mit dem Präprozessor in Konflikt steht:

#define ...
#FF00 // invalid preprocessor token?

Am Ende entschieden sie sich aus irgendeinem Grund, ein x nach einer führenden 0 zu setzen, um hexadezimal zu bezeichnen. Es ist eindeutig, da es immer noch mit einem Zahlenzeichen beginnt und daher kein gültiger Bezeichner sein kann. Es basiert wahrscheinlich auf der Oktalkonvention einer führenden 0.

0xFF00 // definitely not an identifier!
AshleysBrain
quelle
3
Interessant. Ich stelle mir vor, sie hätten ein führendes 0 UND ein nachfolgendes h verwenden können, um hex zu bezeichnen. Das nachfolgende h wäre wahrscheinlich mit dem Typbezeichnersuffix verwechselt worden, z. B. 0xFF00l vs 0FF00hl
zdan
2
Dieses Argument impliziert, dass die Verwendung einer führenden Null zur Bezeichnung von Oktalzahlen vor der Verwendung des hexadezimalen Präfixes "0x" liegt. Ist das wahr?
Andreas Rejbrand
1
Wären sie nicht beide gleichzeitig erfunden worden? Warum sollte es jemals einen geben, aber nicht den anderen?
AshleysBrain
AshleysBrain siehe Antwort von @ Řrřola, warum es gleichzeitig oktal, aber nicht hexadezimal sein kann.
jv42
2
@zdan sie haben es vor langer Zeit benutzt. In der x86-Intel-Assembly muss einem Hex-Literal immer 0 vorangestellt werden, wenn sie mit einem Zeichen beginnen. Zum Beispiel 0xFFAB1234muss geschrieben werden als 0FFAB1234h. Ich erinnere mich an Inline Asm in Pascal, als ich jung war stackoverflow.com/q/11733731/995714
phuclv
27

Es ist ein Präfix, das angibt, dass die Zahl hexadezimal und nicht in einer anderen Basis angegeben ist. Die Programmiersprache C verwendet es, um den Compiler zu informieren.

Beispiel:

0x6400übersetzt in 6*16^3 + 4*16^2 + 0*16^1 +0*16^0 = 25600. Wenn der Compiler liest 0x6400, versteht er, dass die Zahl mit Hilfe des 0x- Terms hexadezimal ist . Normalerweise können wir unter (6400) 16 oder (6400) 8 oder was auch immer verstehen .

Für Binär wäre es:

0b00000001

Hoffe ich habe irgendwie geholfen.

Schönen Tag!

Loyola
quelle
2
Binäre Literale werden nur in C ++ seit C ++ 14 und überhaupt nicht in C unterstützt.
Ruslan
1
Das erklärt nicht warum . Warum konnten Sie das erste Beispiel nicht als schreiben x6400? Das xkönnte immer noch verwendet werden, um hexadezimal zu schließen.
Aaron Franke
12

Die vorhergehende 0 wird verwendet, um eine Zahl in Basis 2, 8 oder 16 anzugeben.

Meiner Meinung nach wurde 0x gewählt, um hex anzugeben, da 'x' wie hex klingt.

Nur meine Meinung, aber ich denke, es macht Sinn.

Schönen Tag!

Johnny Low
quelle
2
Danke für die Antwort! Ich verstehe, dass dies Ihr erster Beitrag auf StackOverflow ist. Die Antwort hätte hilfreicher sein können, wenn Meinungen von Fakten getrennt wären.
vivek_ganesan