Двоичное представление в C - PullRequest
9 голосов
/ 04 декабря 2011

В C почему нет стандартного спецификатора для печати числа в его двоичном формате, например, %b.Конечно, для этого можно написать несколько функций / хаков, но я хочу знать, почему такая простая вещь не является стандартной частью языка.

За этим было какое-то дизайнерское решение?Так как для шестнадцатеричного значения существуют спецификаторы формата для восьмеричного% o и% x, то восьмеричное и шестнадцатеричное являются несколько «более важными», чем двоичное представление.

Поскольку в C / C ++ часто встречаются побитовые операторы, я думаю, что было бы полезно иметь %b или напрямую вводить двоичное представление числа в переменную (способ, которым вводятся шестнадцатеричные числа, такие как int i=0xf2)

Примечание. В таких потоках, как this , обсуждается только часть «как», а не «почему»

Ответы [ 5 ]

3 голосов
/ 04 декабря 2011

Основная причина - «история», я считаю.Первоначальные реализации printf() и др. В AT & T не нуждались в двоичном коде, но требовали восьмеричного и шестнадцатеричного (а также десятичного), так что это было реализовано.Стандарт C89 был достаточно осторожен, чтобы стандартизировать существующую практику - в целом.Было несколько новых частей (локали и, конечно же, прототипы функций, хотя был C ++ для обеспечения «опыта реализации» для них).

Вы можете читать двоичные числа с помощью strtol() et al;указать основание 2. Я не думаю, что есть удобный способ форматирования чисел в разных базах (кроме 8, 10, 16), обратный strtol() - предположительно, это должно быть ltostr().

3 голосов
/ 04 декабря 2011

Вы спрашиваете «почему» так, как будто должна быть четкая и убедительная причина, но реальность такова, что нет технической причины не поддерживать формат %b.

K & R C был создан, чтобы люди, которые формулировали язык, соответствовали тому, что, по их мнению, было их обычным делом.Противоборствующие силы пытались сделать языковую спецификацию максимально простой.

ANSI C был стандартизирован комитетом, члены которого имели различные интересы.Ясно, что %b не в конечном итоге является приоритетом победы.

Языки создаются мужчинами.

2 голосов
/ 04 декабря 2011

Основная причина, как я понимаю, в том, какое двоичное представление следует использовать? свое дополнение? два дополнения? Вы ожидаете фактические биты в памяти или представление абстрактного числа?

Только последний имеет смысл, когда C не предъявляет требований к размеру слова или представлению двоичных чисел. Так что, поскольку в памяти не будет битов, вы наверняка предпочтете прочитать абстрактное число в шестнадцатеричном виде?

Утверждение, что абстрактное представление является «двоичным», может привести к убеждению, что -0b1 ^ 0b1 == 0 может быть истинным или что -0b1 | -0b10 == -0b11


Возможные представления:

Хотя существует только одно значимое шестнадцатеричное представление - абстрактное, число -0x79 может быть представлено в двоичном виде как:

  • -1111001 (номер аннотации)
  • 11111001 (дополнение)
  • 10000111 (дополнение к двум)

@ Эрик убедил меня в этом порядке байтов! = Порядок слева направо ...

проблема усугубляется, когда числа не помещаются в один байт. тот же номер может быть:

  • 1000000001111001 как 16-битное число с прямым порядком байтов, дополняющее один ряд
  • 1111111110000111 как двоичное 16-битное двоичное число с дополнительным порядком байтов
  • 1000011110000000 как однозначное 16-битное число с прямым порядком байтов
  • 1000011111111111 как 16-битное число с прямым порядком байтов, дополняемое двумя числами

Понятия порядкового номера и двоичного представления не применяются к шестнадцатеричным числам, поскольку их никак нельзя считать фактическим представлением битов в памяти.

Все эти примеры предполагают 8-битный байт, который C не дает никаких гарантий (действительно, были исторические машины с 10-битными байтами)


Почему ни одно решение не лучше, чем любое решение:

Очевидно, что можно произвольно выбрать одно представление или оставить его реализацию определенной. Однако:

  • если вы пытаетесь использовать это для отладки побитовых операций (что я вижу в качестве единственной убедительной причины использовать двоичные над шестнадцатеричными), вы хотите использовать что-то близкое к тому, что использует аппаратное обеспечение, что делает невозможным стандартизацию, поэтому вы хочу, чтобы реализация была определена.
  • И наоборот, если вы пытаетесь прочитать битовую последовательность, вам нужен стандартный, а не определенный реализацией формат.
  • И вы определенно хотите, чтобы printf и scanf использовали одно и то же.

Так что мне кажется, что счастливой среды не существует.

1 голос
/ 04 декабря 2011

Одним из ответов может быть то, что шестнадцатеричное форматирование намного компактнее. См., Например, гекса-представление Lister Total Commander.

% b было бы полезно во многих практических случаях. Например, если вы пишете код для анализа сетевых пакетов, вы должны прочитать значения битов, и если printf будет иметь% b, отладка такого кода будет намного проще. Даже если пропустить% b, можно объяснить, когда был разработан printf, это определенно плохая идея.

0 голосов
/ 13 апреля 2016

Я согласен. Я был участником первоначального комитета ANSI C и внес предложение включить двоичное представление в C. Однако по некоторым причинам, упомянутым выше, мне было отказано, хотя я все еще думаю, что это было бы весьма полезно при выполнении, например , побитовые операции и т. д.

Стоит отметить, что комитет ANSI в основном состоял из разработчиков компиляторов, а не пользователей и программистов на Си. Их цель состояла в том, чтобы сделать стандарт понятным для разработчиков компиляторов не обязательно для программистов на C, и иметь возможность сделать это с документом, который был не длиннее, чем нужно, даже если это означало, что это было трудно читать программистам на C.

...