Каким должен быть язык программирования? Анализ и критика Описание языка Компилятор
Отечественные разработки Cтатьи на компьютерные темы Компьютерный юмор Прочее

Шестнадцатиричные и двоичные константы

Язык C установил де-факто стандарт записи шестнадцатеричных чисел. Новые языки, опирающиеся на синтаксис C, копируют этот способ записи. Он привычен, но является ли он естественным?
Шестнадцатеричные и двоичные константы
Попробуем пристально рассмотреть запись вида 0x0123456789abcdef. Вопросов к такой записи немного:

1) Удобно ли писать «abcdef» в языках, где латиница не является основным алфавитом?
2) Является ли префикс «0x» удобным указанием того, что после него последуют шестнадцатеричные цифры?

        Ответом на первый вопрос будет «нет», т.к. употребление «abcdef» требует переключения на латинскую раскладку клавиатуры. Поэтому надо бы предусмотреть такие варианты записи шестнадцатеричных чисел, которые позволили бы набрать их, оставаясь на родной раскладке.

        Что можно поставить в соответствие «abcdef»? Предлагалась такая замена: «abcdef» -> «цодтчп», где
«ц» — цать (т.е. десять)
«о» — одиннадцать,
«д» — двенадцать,
«т» — тринадцать,
«ч» — четырнадцать,
«п» — пятнадцать.

        Не лучший вариант. Во-первых, надо запоминать сокращения — в них есть некая неестественность, потому что эти буквы не идут в алфавите подряд. Во-вторых, буква "О" очень похожа на "0" (ноль) — этому источнику недоразумений уже полсотни лет.

        Самый разумный вариант: «abcdef» -> «абцдеф». Полная калька исходной записи в кириллическом варианте. Транслит наоборот. Не лишено недостатков, ведь в записи «abcdef» — алфавитный порядок букв, а в «абцдеф» — нет. Но остальные варианты хуже.

        Рассмотрим их кратко.
1) «abcdef» -> «абвгде». Русская «В» и «Е» имеют схожие по начертанию латинские «B» и «E», но имеют разный код. Звучащие одинаково на слух «Д» и «D» тоже имеют разный код. Это потенциальный источник путаницы, этого нельзя допустить.
2) «abcdef» -> «ъыьэюя». Вариант экзотический, хотя и в алфавитном порядке. Фрагмент «ъыь» трудноват для запоминания.
3) Замена «abcdef» на символы, один таких способов: «abcdef» -> «. , - : ; =». Не очень удобный вариант для лексического анализатора. Да и любой другой тоже. И какого порядка символов надо будет придерживаться?
4) Замена символов «abcdef» на двухсимвольные последовательности. Примеры:

«abcdef» -> «!0!1!2!3!4!5»
«abcdef» -> «:0:1:2:3:4:5»
«abcdef» -> «^0^1^2^3^4^5»
        Все перечисленные варианты уступают по простоте и внятности «абцдеф». Хотя, возможно, у кого-то найдутся идеи покрасивее.

        А теперь вернёмся к префиксу «0x». Странно вообще, почему эта форма записи так прочно прижилась. Почему «x»? Потому что «hexadecimal»? Но почему выбрана третья буква этого слова, а не первая или седьмая? А зачем нужен «0»? Наверно потому, что запись «x0123456789abcdef» будет принята за идентификатор.

        В языке Euphoria шестнадцатеричные числа записываются так: «#0123456789abcdef». Очень лаконично. В русской раскладке символ «#» отсутствует, но его вполне можно заменить на «№», который находится на той же кнопке.

        Можно попробовать другой способ записи, он выглядит длиннее, но нагляднее. Предлагаются префиксы «16'» и «16"». В таком варианте шестнадцатеричные числа будут выглядеть так:
16' 01 23 45 67 89 аб цд еф
16" 01 23 45 67   89 аб цд еф"
        В первом случае шестнадцатеричные числа допускают употребление одиночных пробелов — сплошной текст труднее воспринимается. Концом константы считается двойной пробел и символы, которые не могут быть употреблены внутри шестнадцатеричного числа.

        Во втором случае концом константы считается второй «"». Цифры внутри апострофов могут разделяться любым количеством пробелов.

        Удивительно, но факт: компьютеры имеют двоичную природу, но в большинстве языков программирования нет возможности записать двоичное число! По аналогии с шестнадцатеричными числами можно ввести двоичные:
2' 0110 1100 0100 1101
2" 0110 1100   0100 1101"
        Элегантная запись, которая понравится новичкам в программировании. Да и профессионалам пригодится при работе с отдельными битами.

        Но было бы неправильным не рассмотреть ещё один (весьма компактный) способ записи, который встречается, к примеру, в HTML или Euphoria.
0xabcdef        традиционный для C-подобных языков способ записи
#abcdef         так записывают в HTML
        У этого способа есть небольшой минус: он «расходует» целый символ из алфавита языка. А как быть с записью двоичных констант? Для этого алфавит нужно уменьшить ещё на один символ? Допустим, вот так:
%01101110       символ «%» обозначает двоичную константу
##11001110      ещё один способ: удваиваем «#»
        Честно говоря, не нравится, потому что, в отличие варианта 16'.... и 2'...., нельзя делать пробелы внутри константы. Эти пробелы облегчают восприятие. Надо сказать, что пробелы — не единственный способ сделать это. В языке Rust облегчают чтение с помощью «_»:
0x9876_abcd
0b0110_0111_1010_1001
Шестнадцатеричные и двоичные константы
        Строка «0b0110_0111_1010_1001» описывает двоичную константу, для этого используется префикс «0b». Автор языка Rust тоже понял, что постоянно проводить в уме преобразования «двоичный код <-> шестнадцатеричный код» — не самое продуктивное занятие.

        Непонятно упорство многих авторов языков предварять шестнадцатеричные константы префиксом «0x». Понятно, откуда она взялась эта традиция. На заре компьютерной эры была распространена восьмеричная система счисления. В C для записи таких чисел использовалась запись с лидирующим нулём. По аналогии использовался лидирующий ноль и в шестнадцатеричных числах, только с добавлением «x». Но восьмеричную систему счисления можно теперь встретить только на маргинальных системах. Поэтому нет необходимости поддерживать единообразие в обозначениях; префикс «0x» сморится нелогично. А вот наш вариант с «16'» и «16"» интуитивно понятен.

Последняя правка: 2014-12-23    16:39

ОценитеОценки посетителей
   ████████████████████ 7 (46.6%)
   █████████ 3 (20%)
   ███ 1 (6.66%)
   ████████████ 4 (26.6%)

Отзывы

     2013/08/01 09:29, Е.В.Геній

А по моему если ужъ программистъ рѣшилъ использовать шестнадцатеричныя константы то ему какъ разъ на переключеніе раскладки плевать. Для чего они вообще въ языкѣ? Свой курсорчикъ нарисовать, или экзотическій сѵмволъ... Въ остальныхъ случаяхъ вполнѣ достаточно десятичнаго представленія... А для компактной записи данныхъ къ примѣру иконокъ или рисунковъ сѵмволами въ текстѣ - есть болѣе прогрессивныя способы кодированія данныхъ въ текстъ, къ примѣру въ форматѣ Base64.

     2013/09/02 23:35, Автор сайта

Евгений, программистам 1С шестнадцатиричные числа точно не нужны :) А вот попробуйте без них написать компилятор… Если хотим язык программирования сделать универсальным, в нём должны быть средства для работы битами. Символы тут ни при чём.

     2014/01/16 11:48, Pensulo

В некоторых реализация Форт используются следующие одиночные префиксы для представления констант со специфической базой исчисления:

% для двоичных, например, %10101010
@ для восьмеричных, например, @177
$ для шестнадцатеричных, например, $FE00
# для собственно десятеричных, например, #-13579

     2014/01/16 12:22, Автор сайта

Это не очень наглядно. Если записать 2”101010”, 8”5874”, 16”FD0A”, 10”1954”, то это будет чуть длиннее, но понятно с первого взгляда.

     2014/01/26 12:34, Pensulo

Предлагаю упростить формат представления чисел с различной базой отсчёта до следующего вида:
база$число
, где база - число в десятеричном виде обозначающее основание исчисления в диапазоне от 2 до 36
число - собственно число представляемое цифрами и буквами латинского алфавита без различия регистра
$ - одиночный символ подобранный так чтобы не конфликтовать с прочими синтаксическими правилами проектируемого языка
Например, 16'12AF представляет собой шестнадцатеричное число 12af

     2014/01/26 17:59, Автор сайта

в диапазоне от 2 до 36

Честно говоря, востребованы только две системы счисления: 2 и 16. Иногда ещё 10, но в особых случаях. Восьмеричная система счисления фактически мертва в языках программирования.

Насчёт одиночного символа. Есть два применение этим константам:
  • для обычной записи чисел
  • для записи кодов символов внутри текстовых литералов
Пример для первого случая:
а = 16"fa09"
b = 2"1111 1010 0000 1001"
и для второго
a = "string 16'30' 2'0011 0001' 10'50'" // что равносильно
a = "string 0 1 2"
Во втором случае эти константы лучше чем-то завершать для ясности. Ибо будет неясно, где заканчивается код символа и где начинается обычный текст. И ещё важно, чтобы способы записи были одинаковы для обоих случаев. В тексте статьи (выше) упомянут вариант с одним символом ', но теперь думается, что это ошибочный путь. А статью собираюсь подправить.

     2014/04/25 03:20, Utkin

Честно говоря, востребованы только две системы счисления: 2 и 16.

Востребованы для чего? Мне кажется уже давно не востребованы. Да, есть по-прежнему некоторый класс задач, где представление числа в виде линейки переключателей имеет смысл, но! Их не так много, чтобы специально ради этого заморачиваться. Мой взгляд прост - кому надо пусть заюзывает внешнюю библиотеку для удобства работы с таким представлением числа. И двоичная и шестнадцатеричная системы счисления пережиток прошлого, да знать надо, для общего развития. Но полную работу отдать специалистам, которые занимаются всяческой электроникой (типа программирования каких-то примитивных гирлянд, управления шаговыми двигателями), но и там примитивные вещи вполне себе делаются в десятичной системе.

     2015/03/19 22:47, rst256

Ответом на первый вопрос будет «нет», т.к. употребление «abcdef» требует переключения на латинскую раскладку клавиатуры.

Эм, а для чего вообще может понадобиться 16-ричные числа в кириллице? Завязывайте вы с Лыськовщиной, кириллице не место в коде!

«16'» и «16"» - это значит "16 угловых минут" и "16 угловых секунд", как нет?
А говорили что очень интуитивно.
Вообще явная запись системы счисления это просто детский сад.
/255.255.255.0 и /24 - не напоминает?

     2015/03/20 11:39, Автор сайта

Кириллица в коде – вполне востребованная вещь. Об этом говорят и итоги голосования. Вы голосуйте, Ваш голос очень важен для нас. Но если Вы не хотите программировать на русском, используйте английский. Языки программирования должны предоставлять свободу выбора. Такая свобода сейчас чаще всего отсутствует.

Для физиков это может означать угловые минуты и секунды. Но у программистов всё по-другому. В языке Ада запись string'length означает вычисление длины строки. Такой способ записи констант обсуждался (в статье есть ссылка), в целом мнение положительное.

     2016/07/21 11:23, Андрей

Надуманная проблема. Сишный вариант представления чисел – один из самых удобных и наглядных и даже перекочевал в некоторые современные языки ассемблера, где, казалось бы, есть давно сформировавшаяся система записи любых чисел. Причина проста как две копейки: такую запись не спутаешь с идентификатором и сразу видна база числа. А маленькая буква 'x', 'o' или 'b' прекрасно выделяют само число от первого нуля и самого префикса. В отличии от кавычек, которые прочно ассоциируются со строкой или символом. Символы '$' и '#' неудобны тем, что сливаются с числом и читаются несколько хуже.

На высказывания некоторых одаренных коментаторов, что мол кому они вообще нужны, эти шестнадцатеричные и тем более двоичные, могу ответить: нам. Нам - это тем, кто специализируется на программировании микроконтроллеров. Десятичные здесь практически не нужны, поскольку необходимо управлять отдельными битами, а не числами в целом. Да и был опыт написания драйверов под винду, под всякие там мышки и прочую ерунду. Там тоже шестнадцатеричные рулят, хотя и не так явно.

Написать отзыв

Написать автору можно на электронную почту mail(аt)compiler.su

Авторизация

Регистрация

Выслать пароль

Карта сайта


Каким должен быть язык программирования?

Анализ и критика

Устарел ли текст как форма представления программы

Русский язык и программирование

Многоязыковое программирование

Синтаксис языков программирования

Синтаксический сахар

Некоторые «вкусности» Алгол-68

«Двухмерный» синтаксис Python

Почему языки с синтаксисом Си популярнее языков с синтаксисом Паскаля?

Должна ли программа быть удобочитаемой?

Стиль языка программирования

Тексто-графическое представление программы

●  Разделители

●  Строки программы

●  Слева направо или справа налево?

Комментарии

●  Длинные комментарии

●  Короткие комментарии

●  Комментарии автоматической генерации документации

●  Нерабочий код

Нужны ли беззнаковые целые?

Шестнадцатиричные и двоичные константы

Условные операторы

Переключатель

Циклы

●  Продолжение цикла и выход из него

Некошерный «goto»

Операции присвоения и проверки на равенство. Возможно ли однаковое обозначение?

Так ли нужны операции «&&», «||» и «^^»?

Постфиксные инкремент и декремент

Почему в PHP для конкатенации строк используется «.»?

Указатели и ссылки в C++

Использование памяти

Почему динамическое распределение памяти – это плохо

Как обеспечить возврат функциями объектов переменной длины?

●  Типы переменного размера (dynamically sized types, DST) в языке Rust

●  Массивы переменной длины в C/C++

●  Размещение объектов в стеке, традиционный подход

●  Размещение объектов переменной длины с использованием множества стеков

●  Размещение объектов переменной длины с использованием двух стеков

●  Реализация двухстековой модели размещения данных

●  Двухстековая модель: тесты на скорость

●  Размещение объектов переменной длины с использованием одного стека

Можно ли забыть о «куче», если объекты переменной длины хранить в стеке

Безопасность и размещение объектов переменной длины в стеке

Массивы, структуры, типы, классы переменной длины

О хранении данных в стеке, вместо заключения

Описание языка

Компилятор

Отечественные разработки

Cтатьи на компьютерные темы

Компьютерный юмор

Прочее

Последние комментарии

2018/04/16 15:09, Олег
Русский язык и программирование

2018/04/02 22:42, rst256
Программирование без программистов — это медицина без врачей

2018/03/25 21:14, Денис Будяк
Энтузиасты-разработчики компиляторов и их проекты

2018/03/21 23:37, Marat
Почему обречён язык Форт

2018/03/10 20:05, Comdiv
«Двухмерный» синтаксис Python

2018/02/24 14:51, Эникейщик
Русской операционной системой должна стать ReactOS

2017/12/12 13:32, Comdiv
Отечественные разработки

2017/11/05 17:26, rst256
Электроника без электронщиков