Mengapa angka heksadesimal diawali dengan 0x?


414

Mengapa angka heksadesimal diawali sebagai 0x? Saya mengerti penggunaan awalan tetapi saya tidak mengerti pentingnya mengapa 0xdipilih.


9
Sekarang saya menyadari bahwa judul dan teks itu mengajukan dua pertanyaan yang sama sekali berbeda. Kebanyakan balasan fokus pada pertanyaan dalam judul. Jawaban atas pertanyaan dalam teks hanyalah "tidak berarti apa-apa - itu hanya awalan yang memberitahu kompiler bahwa integer ditulis dalam heksadesimal".
Andreas Rejbrand

30
Untuk menjadi bertele-tele, orang mungkin juga menafsirkan pertanyaan dalam judul dengan dua cara berbeda: 1) "Mengapa angka heksadesimal diawali dengan 0x, yang bertentangan dengan awalan atau indikator lain?" 2) "Mengapa kita perlu menggunakan awalan saat memasukkan angka heksadesimal? Tentunya kompiler akan mengenali 58A sebagai angka heksadesimal bahkan tanpa awalan?" Jawaban atas interpretasi kedua dari pertanyaan itu sepele. "123" juga merupakan angka heksadesimal.
Andreas Rejbrand

Jawaban:


440

Cerita pendek: The 0menceritakan parser itu berurusan dengan konstanta (dan bukan kata pengenal / pendiam). Masih diperlukan sesuatu untuk menentukan basis angka: itu xadalah pilihan yang sewenang-wenang.

Ceritanya panjang: Pada 60-an, sistem bilangan pemrograman yang lazim adalah desimal dan oktal - mainframe memiliki 12, 24 atau 36 bit per byte, yang dapat dibagi dengan baik oleh 3 = log2 (8).

Bahasa BCPL menggunakan sintaks 8 1234untuk angka oktal. Ketika Ken Thompson menciptakan B dari BCPL, ia menggunakan 0awalan sebagai gantinya. Ini bagus karena

  1. konstanta integer sekarang selalu terdiri dari token tunggal,
  2. pengurai masih bisa langsung tahu itu punya konstanta,
  3. parser dapat segera memberi tahu basis ( 0sama di kedua basis),
  4. ini matematis waras ( 00005 == 05), dan
  5. tidak diperlukan karakter khusus yang berharga (seperti dalam #123).

Ketika C dibuat dari B, kebutuhan untuk bilangan heksadesimal muncul (PDP-11 memiliki kata-kata 16-bit) dan semua poin di atas masih valid. Karena oktal masih diperlukan untuk mesin lain, 0xdipilih secara sewenang-wenang ( 00mungkin dikecualikan sebagai canggung).

C # adalah turunan dari C, jadi ia mewarisi sintaksis.


112
Saya tidak berpikir 0xtentang 00preferensi / kecanggungan. 00akan merusak kode yang ada. 0010sebagai oktal 8, sedangkan 0010sebagai heksidimal akan 16. Mereka tidak dapat menggunakan angka apa pun sebagai indikator digit kedua (kecuali 8atau 9, dan tidak ada yang memiliki signifikansi terkait dengan heksidecimal) sehingga surat adalah suatu keharusan. Dan itu menyisakan 0hatau 0x( H e X idecimal). Dari titik ini tampaknya benar-benar kembali ke preferensi.
GManNickG


23
Menggunakan 0awalan untuk oktal telah menyebabkan begitu banyak masalah selama bertahun-tahun. Khususnya di negara-negara seperti Inggris di mana nomor telepon dimulai dengan a 0. Javascript dan banyak bahasa lain akan menguraikan ini sebagai oktal, mengacaukan nomor sebelum menyimpan. Untuk menambah kesenangan, satu produk basis data yang populer akan secara diam - diam beralih kembali ke penguraian desimal jika nomor mengandung 8atau 9.
Dasar

1
12, 24 dan 36 juga dapat dibagi dengan 4 jadi mengapa mereka tidak memikirkan heksadesimal untuk itu?
phuclv

4
@ LưuVĩnhPhúc Mungkin karena heksadesimal tidak terlalu relevan. Sebagian besar perangkat keras, perangkat lunak, dan dokumentasi waktu pas oktal jauh lebih baik. BCPL pertama kali diimplementasikan pada IBM 7094 36 bit , dengan format instruksi yang dibagi menjadi dua bagian 3 bit dan bagian 2 15 bit; 6 bit karakter; dan dokumentasi dalam oktal. Implementasi awal B adalah pada PDP-7 (18 bit) dan Honeywell GE-945 (36 bit, tetapi dengan pengalamatan 18 bit, dan dukungan untuk 6 dan 9 bit byte). 16 bit PDP-11 keluar setelah B, jadi tidak akan banyak mempengaruhi desain B.
8bittree

97

Catatan: Saya tidak tahu jawaban yang benar, tetapi di bawah ini hanya spekulasi pribadi saya!

Seperti yang telah disebutkan 0 sebelum angka berarti itu oktal:

04524 // octal, leading 0

Bayangkan perlu membuat sistem untuk menunjukkan angka heksadesimal, dan perhatikan bahwa kami bekerja di lingkungan gaya C. Bagaimana kalau diakhiri dengan h like assembly? Sayangnya Anda tidak bisa - ini akan memungkinkan Anda untuk membuat token yang merupakan pengidentifikasi yang valid (mis. Anda bisa memberi nama variabel dengan hal yang sama) yang akan membuat beberapa ambiguitas buruk.

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

Anda tidak dapat memimpin dengan karakter karena alasan yang sama:

xFF00 // also valid identifier

Menggunakan hash mungkin dibuang karena bertentangan dengan preprocessor:

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

Pada akhirnya, untuk alasan apa pun, mereka memutuskan untuk meletakkan x setelah 0 memimpin untuk menunjukkan heksadesimal. Ini tidak ambigu karena masih dimulai dengan karakter angka sehingga tidak bisa menjadi pengidentifikasi yang valid, dan mungkin didasarkan pada konvensi oktal dari 0 terkemuka.

0xFF00 // definitely not an identifier!

3
Menarik. Saya membayangkan mereka bisa menggunakan 0 AND trailing h untuk menunjukkan hex. Trailing h mungkin akan bingung dengan akhiran specifier tipe, misalnya 0xFF00l vs 0FF00hl
zdan

2
Argumen ini menyiratkan bahwa penggunaan nol di depan untuk menunjukkan angka oktal mendahului penggunaan awalan heksadesimal "0x". Apakah ini benar?
Andreas Rejbrand

1
Bukankah mereka berdua diciptakan pada saat yang sama? Mengapa ada satu tapi tidak yang lain?
AshleysBrain

AshleysBrain melihat jawaban oleh @ Řrřola untuk alasan mengapa mungkin ada oktal tetapi tidak heksadesimal pada saat yang sama.
jv42

2
@zdan mereka sudah lama menggunakannya. Dalam perakitan Intel x86 hex hexal harus selalu diawali dengan 0 jika mereka mulai dengan karakter. Misalnya 0xFFAB1234harus ditulis sebagai 0FFAB1234h. Saya ingat dari
asline inm

27

Ini adalah awalan untuk menunjukkan angka dalam heksadesimal daripada di beberapa pangkalan lainnya. Bahasa pemrograman C menggunakannya untuk memberitahu compiler.

Contoh:

0x6400diterjemahkan menjadi 6*16^3 + 4*16^2 + 0*16^1 +0*16^0 = 25600. Ketika kompiler membaca 0x6400, Ia mengerti angka itu heksadesimal dengan bantuan istilah 0x . Biasanya kita dapat mengerti dengan (6400) 16 atau (6400) 8 atau apa pun ..

Untuk biner adalah:

0b00000001

Semoga saya telah membantu dalam beberapa cara.

Selamat siang!


2
Literary biner hanya didukung dalam C ++ sejak C ++ 14, dan tidak didukung dalam C sama sekali.
Ruslan

1
Ini tidak menjelaskan mengapa . Terutama, mengapa Anda tidak bisa menulis contoh pertama x6400? Itu xmasih bisa digunakan untuk menyimpulkan heksadesimal.
Aaron Franke

12

0 sebelumnya digunakan untuk menunjukkan angka dalam basis 2, 8, atau 16.

Menurut pendapat saya, 0x dipilih untuk menunjukkan hex karena 'x' terdengar seperti hex.

Hanya pendapat saya, tapi saya pikir itu masuk akal.

Selamat siang!


2
Terima kasih atas jawabannya! Saya mengerti bahwa ini adalah posting pertama Anda di StackOverflow. Jawabannya bisa lebih membantu jika pendapat dipisahkan dari fakta.
vivek_ganesan
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.