Чому шістнадцяткові числа мають префікс 0x?


414

Чому шістнадцяткові числа мають префікс як 0x? Я розумію використання префікса, але не розумію значення того, чому 0xбуло обрано.


9
Тепер я розумію, що заголовок і текст задають два абсолютно різні питання. Більшість відповідей зосереджені на питанні в заголовку. Відповідь на запитання в тексті просто "це нічого не означає - це лише префікс, що повідомляє компілятору, що ціле число записується шістнадцяткою".
Андреас Рейбранд

30
Щоб бути педантичним, можна також трактувати питання в заголовку двома різними способами: 1) "Чому шістнадцяткові числа мають префікс як 0x на відміну від будь-якого іншого префікса чи індикатора?" 2) "Чому нам потрібно використовувати префікс при введенні шістнадцяткових чисел? Безумовно, компілятор розпізнає 58A як шістнадцятковий номер навіть без префікса?" Відповідь на друге тлумачення питання тривіальна. "123" - це також шістнадцяткове число.
Андреас Рейбранд

Відповіді:


440

Коротка історія:0 каже аналізатору , що має справу з постійною (а не ідентифікатор / зарезервоване слово). Для уточнення бази чисел все ще потрібно щось: xвибір - це довільний вибір.

Довга історія: У 60-х роках переважаючі системи програмування чисел були десятковими і восьмеричними - основні рамки мали 12, 24 або 36 біт на байт, що добре ділиться на 3 = log2 (8).

Мова BCPL використовувала синтаксис 8 1234для вісімкових чисел. Коли Кен Томпсон створив B з BCPL, він використав 0замість цього префікс. Це чудово, тому що

  1. ціла константа тепер завжди складається з одного маркера,
  2. парсер все одно може сказати, що він має постійне значення,
  3. аналізатор може негайно повідомити базу ( 0однакова в обох базах),
  4. це математично здорово ( 00005 == 05), і
  5. ніяких дорогоцінних спеціальних символів не потрібно (як в #123).

Коли C було створено з B, виникла потреба у шістнадцяткових числах (PDP-11 мав 16-бітні слова), і всі пункти вище були все ще дійсними. Оскільки вісімки все ще були потрібні для інших машин, 0xйого довільно обирали ( 00ймовірно, виключали як незручне).

C # є нащадком C, тому він успадковує синтаксис.


112
Я не думаю, що 0xнад 00перевагою / незграбністю. 00порушив би існуючий код. 0010як вісімковий 8, а 0010як би оксидальний 16. Вони не могли використовувати будь-яке число як індикатор другої цифри (за винятком 8або 9, і не має жодного значення, пов’язаного з шістнадцятковим числом), тому літера є обов'язковою. І це залишає або 0hабо 0x( H e X idecimal). З цього моменту, здається, це справді повертається до уподобань.
GManNickG


23
Використання 0префікса для восьмерики протягом багатьох років спричиняло дуже багато проблем. Зокрема, у таких країнах, як Великобританія, де номери телефонів починаються з а 0. Javascript та багато інших мов розбирали б їх як восьмеричний, маніпулюючи числом перед зберіганням. Щоб додати задоволення, один популярний продукт бази даних мовчки переключиться на десятковий синтаксичний розбір, якщо число містить 8або 9.
Основні

1
12, 24 і 36 також поділяються на 4, то чому б вони не придумали для цього шістнадцять?
phuclv

4
@ LưuVĩnhPhúc Можливо, тому, що шістнадцятковий не був дуже актуальним. Більшість апаратних засобів, програмного забезпечення та документації того часу набагато краще підходять до восьмерики. BCPL вперше був реалізований на 36-бітовому IBM 7094 з форматом інструкцій, розділеним на дві 3-бітні частини та 2 15-бітні частини; 6 бітових символів; і документація в восьмериці. Ранні реалізації B були на PDP-7 (18 біт) та Honeywell GE-945 (36 біт, але з 18-бітовою адресацією та підтримкою 6 та 9-бітових байтів). 16-бітний PDP-11 вийшов після B, тому не вплинув би на дизайн B сильно.
8bittree

97

Примітка: я не знаю правильної відповіді, але нижче - це лише моя особиста міркування!

Як було зазначено, число 0 раніше число означає, що це восьмери:

04524 // octal, leading 0

Уявіть, що потрібно створити систему для позначення шістнадцяткових чисел, і зверніть увагу, що ми працюємо в середовищі стилю С. Як щодо закінчення h як збірка? На жаль, ви не можете - це дозволить вам зробити жетони, які є дійсними ідентифікаторами (наприклад, ви могли б назвати змінну тим же самим), що спричинило б деякі неприємні неоднозначності.

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

Ви не можете вести з персонажем з тієї ж причини:

xFF00 // also valid identifier

Використання хеша, ймовірно, було викинуто, оскільки воно суперечить препроцесору:

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

Зрештою, з будь-якої причини вони вирішили поставити х після провідного 0 для позначення шістнадцяткової. Це однозначно, оскільки він все ще починається з символу числа, тому не може бути дійсним ідентифікатором, і, ймовірно, ґрунтується на восьмеричній умові провідного 0.

0xFF00 // definitely not an identifier!

3
Цікаво. Я гадаю, що вони могли використовувати провідний 0 AND кінцевий h для позначення шістнадцяткової. Напевно h було б переплутано із суфіксом специфікатора типу, наприклад, 0xFF00l проти 0FF00hl
zdan

2
Цей аргумент означає, що використання провідного нуля для позначення восьмеричних чисел передує використанню шестнадцяткового префікса "0x". Це правда?
Андреас Рейбранд

1
Чи не були б вони обидва винайдені одночасно? Чому б коли-небудь існувало одне, а не друге?
AshleysBrain

AshleysBrain див. Відповідь @ Řrřola, чому може бути вісімковий, але не шістнадцятковий одночасно.
jv42

2
@zdan вони користувались давно. У збірці x86 Intel шестнадцятковий буквал завжди повинен бути префіксом 0, якщо вони починаються з символу. Наприклад, 0xFFAB1234треба писати як 0FFAB1234h. Я пам'ятаю його від вбудованого асемблері в Паскалі , коли я був молодим stackoverflow.com/q/11733731/995714
phuclv

27

Це приставка, щоб вказати, що число знаходиться в шістнадцятковій, а не в якійсь іншій базі. Мова програмування C використовує його для повідомлення компілятору.

Приклад:

0x6400перекладається 6*16^3 + 4*16^2 + 0*16^1 +0*16^0 = 25600. Коли компілятор читає 0x6400, Він розуміє, що число є шістнадцятковим за допомогою 0x терміна. Зазвичай ми можемо зрозуміти за (6400) 16 або (6400) 8 чи іншим ..

Для двійкових це було б:

0b00000001

Сподіваюся, я якось допоміг.

Хороший день!


2
Бінарні літерали підтримуються лише в C ++, оскільки C ++ 14, і не підтримуються в C взагалі.
Руслан

1
Це не пояснює, чому . Зокрема, чому ви не могли написати перший приклад як x6400? Ці xще можна використовувати для виведення шістнадцяткової.
Аарон Франке

12

Попередній 0 використовується для позначення числа в базі 2, 8 або 16.

На мою думку, 0x було обрано для позначення шістнадцяткової, оскільки "x" звучить як шестнадцятковий.

Просто моя думка, але я думаю, що це має сенс.

Хороший день!


2
Дякую за відповідь! Я розумію, що це ваше перше повідомлення в StackOverflow. Відповідь могла б бути кориснішою, якщо думки відокремлюються від фактів.
vivek_ganesan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.