Является ли обычный символ обычно / всегда без знака в системах без двойного дополнения? - PullRequest
9 голосов
/ 29 мая 2011

Очевидно, что стандарт ничего не говорит об этом, но меня интересует больше с практической / исторической точки зрения: использовали ли системы с арифметикой, не дополняющей двойки, простой тип char без знака? В противном случае у вас могут возникнуть всевозможные странности, например, два представления для нулевого терминатора и невозможность представить все «байтовые» значения в char. Существуют ли такие странные системы?

Ответы [ 3 ]

6 голосов
/ 29 мая 2011

Нулевой символ, используемый для завершения строк, никогда не может иметь двух представлений. Это определено так (даже в C90):

Байт со всеми битами, установленными в 0, называемый нулевым символом, должен существовать в базовом наборе символов выполнения

Так что «отрицательный ноль» на комплементе единиц не подойдет.

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

5 голосов
/ 29 мая 2011

Это правда, что в течение первых 10 или 20 лет серийно выпускаемых компьютеров (1950-х и 60-х годов) были, по-видимому, некоторые разногласия относительно того, как представлять отрицательные числа в двоичном виде.На самом деле было три претендента:

  1. Дополнение к двум, которое не только выиграло войну, но и привело к исчезновению других
  2. Дополнение к одному, -x == ~x
  3. Величина знака, -x = x ^ 0x80000000

Я думаю, что последней важной машиной с комплементом, вероятно, был CDC-6600, ввремя, самая быстрая машина в мире и непосредственный предшественник первого суперкомпьютера. 1.

К сожалению, на ваш вопрос действительно нельзя ответить, не потому что никто здесь не знает ответа: -) но потому что выбор никогда не делался.И это было на самом деле по двум причинам:

  1. Дополнение двух вступило во владение одновременно с байтовыми машинами.Байт-адресация поразила мир с помощью двух дополнений IBM System / 360.Предыдущие машины не имели байтов, только полные слова имели адреса.Иногда программисты помещали символы в эти слова, а иногда просто использовали все слово.(Длина слова варьировалась от 12 бит до 60).

  2. C не было изобретено до десятилетия после байтовых машин и перехода двух дополнений.Пункт № 1 произошел в 1960-х годах, C впервые появился на небольших машинах в 1970-х годах и не захватывал мир до 1980-х годов.

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

Inв любом случае, первый фактически стандартизированный C ("C89") просто указывает "добавляется байт или код нулевого значения" , и из контекста ясно, что они пыталисьбыть независимым от числового формата.Итак, «+0» - это теоретический ответ, но на практике его никогда не существовало.


1.Исторически 6600 был одной из самых важных машин, и не только потому, что он был быстрым.Разработанный самим Сеймуром Крэем, он представил исполнение вне очереди и различные другие элементы, позже все вместе названные «RISC».Хотя другие пытались претендовать на кредит, Сеймур Крей является настоящим изобретателем архитектуры RISC.Нет сомнений, что он изобрел суперкомпьютер.На самом деле трудно назвать прошлый «суперкомпьютер», который он не проектировал.

2 голосов
/ 29 мая 2011

Я полагаю, что для системы было бы почти, но не совсем возможно иметь тип char с одним дополнением, но есть четыре проблемы, которые не все могут быть решены:

  1. Каждый тип данныхдолжен быть представлен в виде последовательности символов, такой, что если все значения символов, составляющие два объекта, сравниваются одинаково, объекты данных, о которых идет речь, будут идентичны.
  2. Каждый тип данных также должен быть представлен в виде последовательности «unsigned char».
  3. Значения без знака, в которые можно разбить любой тип данных, должны образовывать группу, порядок которой равен степени двух.
  4. Я не верю, что стандарт разрешает машине, дополняющей себя, в особом случае значение, которое будет отрицательным нулем, и заставит его вести себя как-то иначе.

Может быть возможно иметь совместимый со стандартами компьютер с типом char, равным единице или дополнению со знаком, если единственным способом получить отрицательный ноль было бы наложение некоторого другого типа данных, и еслиотрицательный ноль по сравнению с положительным нулем.Я не уверен, может ли это соответствовать стандартам или нет.

РЕДАКТИРОВАТЬ

Кстати, если требование № 2 будет смягчено, мне интересно, какие именно требования будутбыть при наложении других типов данных на 'char'?Помимо всего прочего, хотя стандарт и делает совершенно ясным, что нужно иметь возможность выполнять присваивания и сравнения для любых значений 'char', которые могут возникнуть в результате наложения другой переменной на 'char', я не знаю, что это предъявляет какие-либо требованиячто все такие значения должны вести себя как арифметическая группа.Например, мне интересно, какова была бы законность машины, в которой каждая ячейка памяти физически хранилась как 66 битов, причем верхние два бита указывают, было ли значение 64-разрядным целым числом, 32-разрядным дескриптором памяти плюс 32смещение или 64-битное число с плавающей запятой двойной точности?Поскольку стандарт позволяет реализациям делать все, что им нравится, когда арифметическое вычисление превышает диапазон подписанного типа, это предполагает, что подписанные типы не обязательно должны вести себя как группа.

Для большинства типов со знаком существуетнет требования, чтобы тип не мог представлять какие-либо числа за пределами диапазона, указанного в limit.h;Если limit.h указывает, что минимальное значение «int» равно -32767, то для реализации было бы вполне законно разрешить значение -32768, так как любая программа, которая пыталась это сделать, вызывала Undefined Behavior.Ключевой вопрос, вероятно, заключался бы в том, будет ли допустимым, чтобы значение 'char', полученное в результате наложения какого-либо другого типа, давало значение вне диапазона, указанного в limit.h.Интересно, что говорит стандарт?

...