| Hệ đếm |
|---|
| Hệ đếm Hindu - Ả Rập |
|
| Đông Á |
|
| Chữ cái |
|
| Trước đây |
|
| Cơ số |
|
| Non-standard positional numeral systems |
|
| Danh sách hệ đếm |
Trong toán học và khoa học máy tính, hệ cơ số 16 (hay còn gọi là hệ thập lục phân, tiếng Anh: hexadecimal), thường được gọi tắt là thập lục, là một hệ thống số dùng 16 ký tự từ 0 đến 9 và A đến F (không phân biệt chữ hoa hay chữ thường). Phiên bản hiện tại của hệ thống thập lục phân được IBM giới thiệu vào năm 1963. Trước đó, hệ thống tương tự đã được sử dụng trong máy tính Bendix G-15 từ năm 1956.
Chẳng hạn, số 79 trong hệ thập phân, với biểu diễn nhị phân là 01001111, có thể được viết dưới dạng 4F trong hệ thập lục phân (4 = 0100, F = 1111).
| 0hex | = | 0dec | = | 0oct | 0 | 0 | 0 | 0 | |||
| 1hex | = | 1dec | = | 1oct | 0 | 0 | 0 | 1 | |||
| 2hex | = | 2dec | = | 2oct | 0 | 0 | 1 | 0 | |||
| 3hex | = | 3dec | = | 3oct | 0 | 0 | 1 | 1 | |||
| 4hex | = | 4dec | = | 4oct | 0 | 1 | 0 | 0 | |||
| 5hex | = | 5dec | = | 5oct | 0 | 1 | 0 | 1 | |||
| 6hex | = | 6dec | = | 6oct | 0 | 1 | 1 | 0 | |||
| 7hex | = | 7dec | = | 7oct | 0 | 1 | 1 | 1 | |||
| 8hex | = | 8dec | = | 10oct | 1 | 0 | 0 | 0 | |||
| 9hex | = | 9dec | = | 11oct | 1 | 0 | 0 | 1 | |||
| Ahex | = | 10dec | = | 12oct | 1 | 0 | 1 | 0 | |||
| Bhex | = | 11dec | = | 13oct | 1 | 0 | 1 | 1 | |||
| Chex | = | 12dec | = | 14oct | 1 | 1 | 0 | 0 | |||
| Dhex | = | 13dec | = | 15oct | 1 | 1 | 0 | 1 | |||
| Ehex | = | 14dec | = | 16oct | 1 | 1 | 1 | 0 | |||
| Fhex | = | 15dec | = | 17oct | 1 | 1 | 1 | 1 | |||
Lưu ý trong bảng dưới đây: hex = thập lục phân
dec = thập phân
oct = hệ bát phân
Nguồn gốc từ ngữ
Tiếng Anh
IBM đã chọn tiền tố hexa thay vì sexa từ tiếng Latinh. Từ hexadecimal khá lạ lẫm, vì hexa bắt nguồn từ hexi (έξι) trong tiếng Hy Lạp, có nghĩa là 'sáu', trong khi decimal lại đến từ tiếng Latinh và có nghĩa là 'mười'. Mặc dù hexa có thể cũng có nguồn gốc từ Latinh, nhưng deka trong tiếng Hy Lạp gần nghĩa hơn với decem của Latinh, nên có ý kiến cho rằng tên gọi này có chút mâu thuẫn. Từ cổ hơn là sexidecimal nghe như từ Latinh nhưng không chính xác (từ Latinh đúng là sedecim, có nghĩa là 16). Từ này bị loại bỏ vì nó cũng có nghĩa là 'cơ số 60'. Tuy nhiên, tiền tố sexagesimal (cơ số 60) vẫn còn được sử dụng. Trong tài liệu cũ của máy tính Bendix, từ sexadecimal cũng đã xuất hiện. Steven Schwartzman ghi nhận: 'Vì hexadecimal là từ dài, nên thường được viết tắt là hex'. Hexadecimal - hệ thập lục phân - là từ ghép giữa hai nguồn gốc Latinh và Hy Lạp. Nếu theo nguồn gốc Latinh, từ phải là sexadecimal, nhưng những người dùng máy tính có thể dễ dàng gọi ngắn gọn là sex. Giáo sư Donald Knuth chỉ ra rằng tên chính xác phải là senidenary, từ gốc Latinh có nghĩa là 'nhóm 16'. Các từ binary (nhị phân), ternary (tam phân), và quaternary (tứ phân) đều xuất phát từ gốc Latinh, và từ decimal (thập phân) lẽ ra phải là denary (hệ mười).
Gần đây, một hệ thống ký tự khác cho hệ thập lục phân đã được đề xuất, rõ ràng và không gây nhầm lẫn. (Xem thêm: Hexadecimal time)
Biểu diễn số trong hệ thập lục phân
Nhiều số trong hệ thập lục phân gần như tương đương với các số trong hệ thập phân, cả đối với con người lẫn máy tính. Do đó, chúng thường được ký hiệu theo các quy tắc nhất định.
Trên tài liệu in, ký hiệu của hệ này thường được bổ sung bằng một hậu tố, ví dụ như 5A316, 5A3SIXTEEN, hoặc 5A3HEX.
Trong các ngôn ngữ lập trình, thường sử dụng văn bản đơn thuần (plain text) mà không phân biệt chữ hoa, chữ thường như trên tài liệu in. Nhiều phương pháp đánh dấu số thập lục phân đã được sử dụng, và những phương pháp này cũng thường xuất hiện trong tài liệu liên quan đến lập trình.
Một số ký hiệu phổ biến trong các ngôn ngữ lập trình:
- Ada và VHDL sử dụng định dạng số thập lục phân bằng cách gói số theo hệ cơ số, ví dụ như '16#5A3#'. (Lưu ý: Ada hỗ trợ định dạng này cho các hệ cơ số từ nhị phân đến thập lục phân, áp dụng cho cả số nguyên (integer) và số thực (real)).
- C và các ngôn ngữ lập trình tương tự (như C++, C#, Java và Javascript) sử dụng tiền tố '0x' để biểu thị số thập lục phân, ví dụ: '0x5A3'. Số 0 dẫn đầu giúp bộ phân tích mã (parser) nhận diện số, trong khi chữ 'x' biểu thị hệ thập lục phân – khác với 0 cho hệ bát phân (octal). Chữ 'x' có thể viết hoa (0X) hoặc viết thường (0x), nhưng thường thấy dưới dạng viết thường.
- Các shell trên hệ thống *nix (phần mềm điều khiển mệnh lệnh trên các hệ điều hành tương tự Unix) sử dụng mã escape với tổ hợp ký tự '\x0FF' trong các biểu thức (expression), và '0xFF' cho các hằng số (constant).
- Trong HTML, số thập lục phân được biểu thị bằng cách dùng chữ 'x': ֣ tương đương với ֣ – với trình duyệt web của bạn và ֣ theo thứ tự; (dấu trong tiếng Hebrew Hebrew accent munah). Mã màu dùng hệ thập lục phân thường được biểu thị bằng tiền tố '#', chẳng hạn '#FFFFFF' (màu trắng).
- Ngoài ra, một số ngôn ngữ assembly chỉ định số thập lục phân bằng cách thêm chữ 'h' vào cuối số (nếu số bắt đầu bằng chữ và đứng sau số 0 để chỉ định rằng đây là số thập lục phân), ví dụ: '0A3Ch', '5A3h'.
- Postscript sử dụng tiền tố '16#' để chỉ định số thập lục phân.
- Common Lisp sử dụng tiền tố '#x' hoặc '#16r'.
- Pascal, cùng với các assembler khác (AT&T, Motorola) và một số phiên bản BASIC, dùng tiền tố '$', ví dụ: '$5A3'.
- Ngôn ngữ lập trình Smalltalk sử dụng tiền tố '16r'. Lưu ý rằng Smalltalk cũng chấp nhận định dạng <gốc hệ số>r<dãy số> - gốc hệ số là một số từ 2 trở lên (ví dụ: 2r1110 bằng 10r14 hoặc 16rE), với các ký tự và số thuộc bộ ASCII, từ 0-9 và A-Z. Một số phiên bản của Smalltalk cho phép các số thập phân sau dấu chấm '.' biểu thị số thập lục phân dấu động (floating point number) (và các gốc hệ số khác).
- Một số phiên bản BASIC, đặc biệt là các biến thể của Microsoft như QBasic và Visual Basic, sử dụng tiền tố '&H' để biểu thị số thập lục phân, ví dụ: '&H5A3'; các phiên bản khác như BBC BASIC chỉ dùng '&' (dùng để biểu thị hệ bát phân (octal) trong BASIC của Microsoft).
- Các ký hiệu như
X'5A3'cũng thường thấy; PL/I sử dụng ký hiệu như vậy. - Donald Knuth đã giới thiệu cách dùng các kiểu chữ khác nhau để biểu thị hệ cơ số trong sách của ông The TeXbook. Trong hệ thống ký hiệu của ông, số thập lục phân được biểu thị bằng các chữ kiểu máy đánh chữ (typewriter type), ví dụ: 5A3
Do không có quy định thống nhất, các quy ước trên thường được áp dụng, đôi khi ngay cả trong cùng một tài liệu. Tuy nhiên, vì các quy ước này khá rõ ràng và khác biệt nên hiếm khi gây ra sự nhầm lẫn.
Ký hiệu phổ biến nhất là tiền tố '0x' hoặc ký hiệu chỉ số 16 dưới dạng chỉ số (subscript-based), đều đại diện cho số thập lục phân. Ví dụ, cả hai số 0x2BAD và 2BAD16 đều biểu thị số thập phân 11181 (hoặc 1118110).
Trong những năm đầu của lịch sử máy tính, việc chọn các ký tự từ A đến F để thay thế cho các số tiếp theo chưa được chấp nhận rộng rãi. Sau năm 1950, một số hệ thống máy tính đã chọn cách dùng các số từ 0 đến 5 cùng với một cấu trúc mã (macron) để biểu thị giá trị từ 10 đến 15. Người dùng máy tính Bendix còn sử dụng các chữ cái từ 'U' đến 'Z'.
Ứng dụng
Hệ thập lục phân được ứng dụng rộng rãi trong lập trình HTML và CSS (hoặc định dạng trang web). Trong các ngôn ngữ này, bộ ba số thập lục phân (hex triplet) được sử dụng để chỉ định màu sắc trên các trang web, bắt đầu bằng dấu '#'. Dấu này cũng được dùng để biểu thị các giá trị thập lục phân. Để định dạng màu sắc với 24 bit, công thức #RRGGBB ('Đỏ, Xanh lá, Xanh dương') được áp dụng. Trong công thức này, 'RR' ('Red Red') thể hiện sắc độ đỏ, 'GG' ('Green Green') cho sắc xanh lá (dù thực ra là màu xanh lá cây, nhưng gọi là vàng để phân biệt với màu xanh dương tiếp theo), và 'BB' ('Blue Blue') cho sắc xanh dương, giúp xác định độ sắc của màu. Ví dụ, màu đỏ với giá trị thập phân (238, 9, 63) sẽ được mã hóa thành #EE093F. Công thức này được áp dụng từ hệ thống màu sắc của cửa sổ X (X Window System).
Hệ thập lục phân còn được sử dụng trong nhiều lĩnh vực kỹ thuật máy tính khác và là phương pháp phổ biến để biểu diễn giá trị của một byte, thông qua dãy ký tự (string) dễ đọc cho con người. Mỗi giá trị của một byte (tổng cộng 256 giá trị) đều có thể được thể hiện bằng hệ thập lục phân. Một số người cho rằng hệ thống ASCII 8-bit là phương pháp khả thi để biểu diễn giá trị, nhưng hệ ASCII bao gồm các ký tự không in được (các ký tự điều khiển (control characters)), không phải lúc nào cũng phù hợp với mục đích này.
Trong các URL, các ký tự đặc biệt có thể được biểu thị bằng mã thập lục phân, bắt đầu bằng dấu phần trăm (%), ví dụ như http://vi.wikipedia.org/wiki/Trang%20Ch%C3%ADnh.
Công thức quy định cách viết địa chỉ IPv6, mỗi nhóm số 16 bit được biểu diễn bằng số thập lục phân, nhằm giúp việc đọc và sao chép các địa chỉ dài 128-bit trở nên dễ dàng hơn.
Phân số
Như các hệ đếm khác, hệ thập lục phân cũng có thể diễn tả phân số (vulgar fraction), nhưng thường gặp hiện tượng chu kỳ lặp lại số thập phân (recurring digits), do số 16 chỉ có một yếu tố nguyên tố:
| 1/ 0x1 | 0x1 | 1/ 0x5 | 0x0.3 | 1/ 0x9 | 0x0.1C7 | 1/ 0xD | 0x0.13B | ||||
| 1/ 0x2 | 0x0.8 | 1/ 0x6 | 0x0.2A | 1/ 0xA | 0x0.19 | 1/ 0xE | 0x0.1249 | ||||
| 1/ 0x3 | 0x0.5 | 1/ 0x7 | 0x0.249 | 1/ 0xB | 0x0.1745D | 1/ 0xF | 0x0.1 | ||||
| 1/ 0x4 | 0x0.4 | 1/ 0x8 | 0x0.2 | 1/ 0xC | 0x0.15 | 1/ 0x10 | 0x0.1 |
Vì cơ số 16 là bình phương của 4 (4²), phân số trong hệ thập lục phân có thể có chu kỳ lặp lại đặc biệt nhiều hơn so với hệ thập phân. Chu kỳ thập phân xuất hiện khi mẫu số, với thừa số thấp nhất (denominator in lowest terms), có một yếu tố nguyên tố không xuất hiện trong cơ số. Đối với số thập lục phân, tất cả phân số có mẫu số không phải là tích của một số mũ 2 sẽ tạo ra chu kỳ lặp lại số thập phân.
Hài hước
Hệ thập lục phân đôi khi được sử dụng trong các trò đùa của lập trình viên, vì một số từ có thể được tạo ra từ các số thập lục phân. Ví dụ như từ 'dead' (chết), 'beef' (thịt bò), 'babe' (người yêu), và từ 'c0ffee' (cà phê) khi sử dụng các ký tự phù hợp. Những trò đùa này thường thấy trên các trang web và trong các ứng dụng. Do khả năng nhận diện dễ dàng của các từ kiểu này, các công cụ kiểm tra lỗi (debugging setup) đôi khi sử dụng chúng để gán giá trị khởi đầu cho các biến trong bộ nhớ, giúp lập trình viên tìm ra các biến chưa được khởi tạo (not initialised). Một số người thêm chữ 'H' vào cuối con số để chỉ định nó là số thập lục phân. Quy tắc này đôi khi cũng được áp dụng trong ngữ pháp của các ngôn ngữ lập trình assembly cổ của Intel, cho phép tạo ra các từ và câu mới như 1517ADEADB17CH.
Một ví dụ khác là con số ma (magic number) thường gặp trong các tệp hệ thống phân bổ FAT Mach-O và chương trình Java, với giá trị là 'CAFEBABE' (cà phê cô bé).
Hóa đơn của Knuth có giá trị một đô la theo hệ thập lục phân (256 xu = 16), tương đương với $2.56.
Dưới đây là một bảng hài hước về hệ thập lục phân:
- 3x12=36
- 2x12=24
- 1x12=12
- 0x12=18
Ba hàng đầu tiên là các tích của số 12, trong khi hàng cuối cùng '0x12' trong hệ thập lục phân lại tương đương với 18.
Giá trị 0xdeadbeef ('ox dead beef' - thịt bò chết) đôi khi được dùng để đánh dấu bộ nhớ chưa được khởi tạo (uninitialized memory).
Chuyển đổi sang hệ nhị phân
Khi làm việc với máy tính, chúng ta thường xử lý dữ liệu nhị phân, nhưng việc xử lý số trong hệ thập lục phân lại đơn giản hơn so với hệ nhị phân (chỉ có 0 và 1). Mặc dù chúng ta quen thuộc hơn với hệ thập phân, việc chuyển số từ nhị phân sang thập lục phân dễ dàng hơn so với việc chuyển sang thập phân, vì mỗi ký tự thập lục phân tương ứng với 4 bit nhị phân (410).
Hãy xem xét việc chuyển đổi số 11112 sang hệ thập phân. Do mỗi vị trí trong hệ nhị phân (cơ số 2) chỉ có thể nhận giá trị 0 hoặc 1, việc xác định giá trị của số ở mỗi vị trí từ phải sang trái là khá đơn giản:
- 00012 = 110
- 00102 = 210
- 01002 = 410
- 10002 = 810
Vậy thì:
| 11112 | = 810 + 410 + 210 + 110 |
| = 1510 |
Đây là một phép toán đơn giản, nhưng yêu cầu tới bốn phép cộng. Tuy nhiên, với một chút thực hành, 11112 có thể được chuyển đổi trực tiếp sang F16 chỉ với một phép tính (xem Biểu thị số thập lục phân). Khi số nhị phân lớn, việc chuyển đổi sang hệ thập phân có thể trở nên phức tạp và tẻ nhạt. Ngược lại, khi chuyển từ nhị phân sang thập lục phân, chúng ta chỉ cần nhóm các bit thành từng nhóm 4, chuyển mỗi nhóm thành một ký tự thập lục phân và giữ nguyên vị trí nhóm đó. Ví dụ dưới đây cho thấy sự phức tạp của việc chuyển đổi từ nhị phân sang thập phân.
| 010111101011010100102 | = 26214410 + 6553610 + 3276810 + 1638410 + 819210 + 204810 + 51210 + 25610 + 6410 + 1610 + 210 |
| = 38792210 |
So với ví dụ trên, việc chuyển đổi cùng một số sang hệ thập lục phân dễ dàng hơn rất nhiều:
| 010111101011010100102 | = | 0101 | 1110 | 1011 | 0101 | 00102 |
| = | 5 | E | B | 5 | 216 | |
| = | 5EB5216 | |||||
Chúng ta cũng có thể chuyển đổi từ hệ thập lục phân về nhị phân một cách đơn giản như ví dụ trên.
Sử dụng hệ bát phân cũng là một phương pháp hiệu quả để xử lý dữ liệu trong máy tính (nhóm 3 bit thay vì nhóm 4); tuy nhiên, lợi thế lớn nhất của hệ thập lục phân so với bát phân là việc biểu diễn một byte (octet) chỉ cần hai ký tự thập lục phân. Điều này có nghĩa là nếu chúng ta có giá trị của một word (thường là 4 byte), việc nhận diện giá trị từng byte là rất dễ dàng; ngược lại, nếu chúng ta biết giá trị của từng byte, việc ghép chúng lại thành một word cũng rất đơn giản.
Chuyển đổi từ các hệ cơ số khác
Phương pháp chia lấy dư trong hệ cơ số gốc
Cách chuyển đổi một số sang hệ thập lục phân tương tự như việc chuyển đổi giữa các hệ cơ số khác, bằng cách sử dụng phép chia lấy số nguyên và số dư trong hệ cơ số gốc. Về lý thuyết, phương pháp này có thể áp dụng cho bất kỳ cặp hệ cơ số nào. Tuy nhiên, trong thực tế và kỹ thuật máy tính, phương pháp này thường được sử dụng với hệ thập phân và nhị phân. (Đối với hệ nhị phân, còn có những phương pháp nhanh hơn.)
Ví dụ, nếu d là số thập phân cần chuyển đổi, thì dãy số hihi-1...h2h1 sẽ đại diện cho số trong hệ thập lục phân tương ứng. Dưới đây là cách tính dãy số h:
- 1. Hi:= d mod 16
- ('mod' (modulus): phép chia lấy dư, thực hiện phép chia số nguyên và lấy số dư - ví dụ 17 mod 5 = 2 vì 17/5 = 3, dư 2.)
- 2.
- 3. Nếu d == 0, kết quả là dãy số h); nếu không, quay lại bước 1.
- 1. Hi:= d mod 16
Phần dưới đây trình bày quy trình của thuật toán trong ngôn ngữ JavaScript để chuyển đổi bất kỳ số thập phân nào sang hệ thập lục phân, với kết quả trả về dưới dạng chuỗi ký tự. Ví dụ này nhằm minh họa quy trình thuật toán (có thể áp dụng cho các ứng dụng xử lý khác). Để sử dụng thuật toán này với dữ liệu cụ thể, bạn có thể dùng các phép toán bitwise.
function toHex(d) { /* chuyển đổi sang hệ thập lục phân */ var r = d % 16; if(d-r==0) {return toChar(r);} else {return toHex((d-r)/16)+toChar(r);} } function toChar(n) { /* chuyển đổi số nguyên sang ký tự có thể đọc được */ var alpha = '0123456789ABCDEF'; return alpha.charAt(n); }
Lưu ý rằng cơ số '16' ở trên có thể được thay thế bằng bất kỳ cơ số nào khác (chẳng hạn như hệ nhị phân (2), tam phân (3), bát phân (8), v.v...). Dưới đây là một ví dụ minh họa bằng ngôn ngữ C++ để in ra số tương ứng trong bất kỳ hệ cơ số nào từ một số thập phân.
const alpha = '0123456789ABCDEF'; void printinbase(long d, short b) { // in số ở hệ cơ số b tương ứng với số thập phân d short r = d % b; if (d-r) printinbase(d/b,b); cout << alpha[r]; }
Cộng và nhân trong hệ thập lục phân
Chúng ta có thể thực hiện phép biến đổi bằng cách phân tích giá trị của từng chữ số (như hàng đơn vị, hàng chục, hàng trăm trong hệ thập phân), sau đó chuyển đổi từng giá trị sang hệ thập lục phân, rồi thực hiện các phép toán cộng hoặc nhân với các số này trong hệ thập lục phân. Khi tính toán nhân, nên sử dụng bảng cửu chương của hệ thập lục phân để dễ dàng so sánh, vì phần lớn mọi người chỉ quen với bảng cửu chương của hệ thập phân.
Ví dụ: 12310 cộng với 45610
10010 cộng 2010 cộng 310 + 40010 cộng 5010 cộng 610 """""-- hay 6416 cộng 1416 cộng 316 + 19016 cộng 3216 cộng 616 """""-- 1F416 cộng 4616 cộng 916 11 (Nhớ) """- 1F416 50010 + 4616 + 7010 916 910 "- "- 24316 57910
Chuyển đổi thông qua hệ nhị phân
Vì máy tính chủ yếu sử dụng hệ nhị phân, nên phương pháp chuyển đổi thường là qua hệ nhị phân trước, sau đó kết nối trực tiếp giữa hệ thập lục phân và nhị phân để chuyển sang hệ thập lục phân.
Nhìn nhận về hệ thập lục phân qua lăng kính của truyền thông và điện ảnh
Trong tập phim hoạt hình dài tập The Simpsons mang tên Treehouse of Horror VI (Ngôi nhà ma quái trên cây VI), nhân vật Homer rơi vào một không gian 3 chiều, (Homer³), nơi các số thập lục phân (46 72 69 6e 6b 20 52 75 6c 65 73 21) lơ lửng trong 'vùng đất ba chiều' (3-D land). Khi tra cứu các giá trị thập lục phân này trong bảng ASCII, ta nhận được các ký tự ghép lại thành cụm từ tiếng Anh 'Frink rules!' (trừ hai dấu ngoặc kép) - có nghĩa là 'Frink trị vì!' hoặc 'Frink là vua'.
Trong chương trình truyền hình ReBoot, có một nhân vật mang tên Hexadecimal (hệ thập lục phân).
- Số Hex
- Hệ thập phân
- Hệ nhị phân
Liên kết bên ngoài
- Trụ sở Intuitor Hex - Trang web chuyên cung cấp thông tin về cách chuyển đổi từ hệ số thập phân sang hệ thập lục phân.
- Các phương pháp chuyển đổi cơ bản
- Leet Key Lưu trữ 2020-02-26 tại Wayback Machine - Một tiện ích mở rộng cho Firefox giúp chuyển đổi và nhập liệu giữa ASCII và số thập lục phân.
- Bits of Meaning (pdf) Lưu trữ 2006-06-14 tại Wayback Machine - Giới thiệu về số học máy tính trong hệ thống Bendix G-15 của IBM.
- Cơ bản về số thập lục phân
- Hướng dẫn về số thập lục phân Lưu trữ 2006-04-22 tại Wayback Machine.
- Màu sắc thập lục phân - Cách biểu diễn màu sắc bằng hệ thập lục phân.
