Tại sao các số thập lục phân có tiền tố bằng 0x?


414

Tại sao các số thập lục phân có tiền tố là 0x? Tôi hiểu cách sử dụng tiền tố nhưng tôi không hiểu tầm quan trọng của lý do tại sao 0xđược chọn.


9
Bây giờ tôi nhận ra rằng tiêu đề và văn bản hỏi hai câu hỏi hoàn toàn khác nhau. Hầu hết các câu trả lời tập trung vào câu hỏi trong tiêu đề. Câu trả lời cho câu hỏi trong văn bản chỉ đơn giản là "nó không có nghĩa gì cả - nó chỉ là một tiền tố cho trình biên dịch biết rằng số nguyên được viết dưới dạng thập lục phân".
Andreas Rejbrand

30
Để được mô tả, người ta cũng có thể diễn giải câu hỏi trong tiêu đề theo hai cách khác nhau: 1) "Tại sao các số thập lục phân có tiền tố là 0x, trái ngược với bất kỳ tiền tố hoặc chỉ báo nào khác?" 2) "Tại sao chúng ta cần sử dụng tiền tố khi nhập số thập lục phân? Chắc chắn trình biên dịch sẽ nhận ra 58A là số thập lục phân ngay cả khi không có tiền tố?" Câu trả lời cho cách giải thích thứ hai của câu hỏi là tầm thường. "123" cũng là một số thập lục phân.
Andreas Rejbrand

Câu trả lời:


440

Truyện ngắn: Người 0kể cho trình phân tích cú pháp nó xử lý một hằng số (và không phải là từ định danh / từ dành riêng). Một cái gì đó vẫn cần thiết để xác định cơ sở số: đó xlà một lựa chọn tùy ý.

Câu chuyện dài: Trong thập niên 60, các hệ thống số lập trình phổ biến là thập phân và bát phân - các khung hình chính có 12, 24 hoặc 36 bit trên mỗi byte, chia hết cho 3 = log2 (8).

Ngôn ngữ BCPL đã sử dụng cú pháp 8 1234cho các số bát phân. Khi Ken Thompson tạo B từ BCPL, anh ta đã sử dụng 0tiền tố thay thế. Điều này thật tuyệt vì

  1. một hằng số nguyên bây giờ luôn bao gồm một mã thông báo duy nhất
  2. trình phân tích cú pháp vẫn có thể nói ngay rằng nó có một hằng số,
  3. trình phân tích cú pháp có thể ngay lập tức cho biết cơ sở ( 0giống nhau trong cả hai cơ sở),
  4. về mặt toán học lành mạnh (00005 == 05 ) và
  5. không có ký tự đặc biệt quý giá là cần thiết (như trong #123).

Khi C được tạo từ B, nhu cầu về số thập lục phân nảy sinh (PDP-11 có các từ 16 bit) và tất cả các điểm trên vẫn còn hiệu lực. Vì các quãng tám vẫn cần thiết cho các máy khác, 0xđược chọn tùy ý ( 00có thể bị loại trừ vì khó xử).

C # là hậu duệ của C, vì vậy nó kế thừa cú pháp.


112
Tôi không nghĩ 0xqua 00là sở thích / lúng túng. 00sẽ phá vỡ mã hiện có. 0010như bát phân là 8, trong khi 0010như thập lục phân sẽ là 16. Họ không thể sử dụng bất kỳ số nào làm chỉ báo chữ số thứ hai (ngoại trừ 8hoặc 9không giữ bất kỳ ý nghĩa nào liên quan đến thập lục phân) vì vậy một chữ cái là bắt buộc. Và điều đó để lại 0hhoặc 0x( H e X idecimal). Từ thời điểm này, có vẻ như nó thực sự trở lại ưu tiên.
GManNickG


23
Sử dụng 0tiền tố cho bát phân đã gây ra rất nhiều vấn đề trong những năm qua. Đáng chú ý là ở các quốc gia như Vương quốc Anh nơi số điện thoại bắt đầu bằng a 0. Javascript và nhiều ngôn ngữ khác sẽ phân tích các ngôn ngữ này dưới dạng bát phân, xáo trộn số trước khi lưu trữ. Để thêm phần thú vị, một sản phẩm cơ sở dữ liệu phổ biến sẽ âm thầm chuyển trở lại phân tích cú pháp thập phân nếu số đó chứa một 8hoặc 9.
Cơ bản

1
12, 24 và 36 cũng chia hết cho 4, vậy tại sao họ không nghĩ đến hệ thập lục phân cho điều đó?
phuclv

4
@ LưuViênPhúc Có lẽ vì thập lục phân không liên quan lắm. Hầu hết các phần cứng, phần mềm và tài liệu thời gian phù hợp với bát phân tốt hơn nhiều. BCPL lần đầu tiên được triển khai trên IBM 7094 36 bit , với định dạng hướng dẫn được chia thành hai phần 3 bit và 2 phần 15 bit; Ký tự 6 bit; và tài liệu trong bát phân. Việc triển khai sớm của B là trên PDP-7 (18 bit) và Honeywell GE-945 (36 bit, nhưng có địa chỉ 18 bit và hỗ trợ cho các byte 6 và 9 bit). PDP-11 16 bit xuất hiện sau B, do đó sẽ không ảnh hưởng nhiều đến thiết kế của B.
8bittree

97

Lưu ý: Tôi không biết câu trả lời chính xác, nhưng dưới đây chỉ là suy đoán cá nhân của tôi!

Như đã đề cập 0 trước một số có nghĩa là số bát phân:

04524 // octal, leading 0

Hãy tưởng tượng bạn cần phải đưa ra một hệ thống để biểu thị các số thập lục phân và lưu ý rằng chúng ta đang làm việc trong môi trường kiểu C. Làm thế nào về kết thúc với h như lắp ráp? Thật không may, bạn không thể - nó sẽ cho phép bạn tạo mã thông báo là số nhận dạng hợp lệ (ví dụ: bạn có thể đặt tên cho một biến giống nhau) sẽ tạo ra một số sự mơ hồ khó chịu.

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

Bạn không thể lãnh đạo với một nhân vật vì lý do tương tự:

xFF00 // also valid identifier

Sử dụng hàm băm có thể bị loại bỏ vì nó xung đột với bộ tiền xử lý:

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

Cuối cùng, vì bất kỳ lý do gì, họ đã quyết định đặt dấu x sau số 0 đứng đầu để biểu thị thập lục phân. Không rõ ràng vì nó vẫn bắt đầu bằng một ký tự số nên không thể là định danh hợp lệ và có thể dựa trên quy ước bát phân của số 0 đứng đầu.

0xFF00 // definitely not an identifier!

3
Hấp dẫn. Tôi tưởng tượng họ có thể đã sử dụng 0 và dấu h hàng đầu để biểu thị hex. H theo sau có lẽ đã bị nhầm lẫn với hậu tố chỉ định loại, ví dụ 0xFF00l so với 0FF00hl
zdan

2
Đối số này ngụ ý rằng việc sử dụng số 0 đứng đầu để biểu thị số bát phân trước khi sử dụng tiền tố "0x" thập lục phân. Điều này có đúng không?
Andreas Rejbrand

1
Cả hai sẽ không được phát minh cùng một lúc? Tại sao lại có cái này mà không phải cái kia?
AshleyBrain

AshleyBrain xem câu trả lời của @ rřola về lý do tại sao có thể có bát phân nhưng không phải là thập lục phân cùng một lúc.
jv42

2
@zdan họ đã dùng nó từ lâu rồi. Trong x86 Intel lắp ráp, một chữ hex phải luôn có tiền tố bằng 0 nếu chúng bắt đầu bằng một ký tự. Ví dụ 0xFFAB1234phải được viết là 0FFAB1234h. Tôi nhớ nó từ asm nội tuyến trong Pascal khi tôi còn trẻ stackoverflow.com/q/11733731/995714
phuclv

27

Đó là một tiền tố để chỉ ra số ở dạng thập lục phân chứ không phải trong một số cơ sở khác. Ngôn ngữ lập trình C sử dụng nó để báo cho trình biên dịch.

Thí dụ:

0x6400dịch sang 6*16^3 + 4*16^2 + 0*16^1 +0*16^0 = 25600. Khi trình biên dịch đọc 0x6400, Nó hiểu số là thập lục phân với sự trợ giúp của thuật ngữ 0x . Thông thường chúng ta có thể hiểu theo (6400) 16 hoặc (6400) 8 hoặc bất cứ điều gì ..

Đối với nhị phân, nó sẽ là:

0b00000001

Hy vọng tôi đã giúp một cách nào đó.

Ngày tốt!


2
Chữ nhị phân chỉ được hỗ trợ trong C ++ kể từ C ++ 14, và hoàn toàn không được hỗ trợ trong C.
Ruslan

1
Điều này không giải thích tại sao . Đặc biệt, tại sao bạn không thể viết ví dụ đầu tiên là x6400? Các xvẫn có thể được sử dụng để suy ra hệ thập lục phân.
Aaron Franke

12

Số 0 trước được sử dụng để chỉ ra một số trong cơ sở 2, 8 hoặc 16.

Theo tôi, 0x được chọn để biểu thị hex vì 'x' nghe giống như hex.

Chỉ là ý kiến ​​của tôi, nhưng tôi nghĩ nó có ý nghĩa.

Ngày tốt!


2
Cảm ơn câu trả lời! Tôi hiểu rằng đây là bài viết đầu tiên của bạn trên StackOverflow. Câu trả lời có thể hữu ích hơn nếu ý kiến ​​được tách ra khỏi thực tế.
vivek_ganesan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.