Вопрос по standards, c++, long-integer, language-lawyer –  байты, но байты не обязательно являются октетами). Потому что именно так их определяет Стандарт.

50

я стандарт C ++, я всегда понимал, что размеры интегральных фундаментальных типов в C ++ были следующими:

sizeof(char) <= sizeof(short int) <= sizeof(int) <= sizeof(long int)

Я вывел это из 3.9.1 / 2:

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

Далее размерchar описывается в 3.9.1 / как:

[...] достаточно большой, чтобы хранить любой элемент базового набора символов реализации.

1.7 / 1 определяет это в более конкретных терминах:

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

Это приводит меня к следующему выводу:

1 == sizeof(char) <= sizeof(short int) <= sizeof(int) <= sizeof(long int)

гдеsizeof говорит нам, сколько байтов тип. Кроме того, это определяется реализацией, сколько битов в байте. Большинство из нас, вероятно, привыкли иметь дело с 8-битными байтами, но Стандарт говорит, что естьn биты в байте.

Вэта почтаАльф П. Штейнбах говорит:

long гарантируется (как минимум) 32 бита.

Это противоречит всему, что, как я понимаю, соответствует размеру основных типов в C ++ в соответствии со Стандартом. Обычно я просто игнорировал бы это утверждение, поскольку новичок ошибался, но, поскольку это был Альф, я решил, что его стоит продолжить.

Итак, что вы говорите? Гарантируется ли стандарт длиной не менее 32 бит? Если это так, пожалуйста, уточните, как предоставляется эта гарантия. Я просто не вижу этого.

Стандарт C ++, в частности, гласит, что для того, чтобы знать C ++, вы должны знать C (1.2 / 1)1

Стандарт C ++ неявно определяет минимальный предел значенийlong можно разместить, чтобы бытьLONG_MIN-LONG_MAX 2

Так что независимо от того, насколько большойlong это должно быть достаточно большим, чтобы держать LONG_MIN в LONG_MAX.

Но Альф и другиеконкретный что long должен быть не менее 32 бит. Это то, что я пытаюсь установить. Стандарт C ++ явно указывает, что число битов в байте не указано (это может быть 4, 8, 16, 42). Так как же получается соединение, способное вместить числа?LONG_MIN-LONG_MAX быть не менее 32 бит?

(1) 1.2 / 1: Следующие ссылочные документы необходимы для применения этого документа. Для датированных ссылок применимо только указанное издание. Для недатированных ссылок применяется самое последнее издание ссылочного документа (включая любые изменения).

ISO / IEC 2382 (все части), Информационные технологии. СловарьISO / IEC 9899: 1999, Языки программирования - CISO / IEC 10646-1: 2000, Информационные технологии. Универсальный многооктетный набор кодированных символов (UCS). Часть 1. Архитектура и базовая многоязычная плоскость

(2) Определено в<climits> как:

LONG_MIN -2147483647 // -(2^31 - 1)
LONG_MAX +2147483647 //   2^31 - 1
@Mark: есть машины, которые могут адресовать и работать только с количеством больше 8 бит, например, 32-битные слова, там обычно используется char == int == long == 32-битная. ybungalobill
Ну, я думаю, если кто-то придумает способ хранения(2^32)-1 отдельные значения в менее чем 32 бита, тогда в длинном не может быть 32 бита. Однако на любой двоичной платформе, пока математика верна, у вас будет 32 бита. Anon.
@Alf: сжато, определенно. Исправьте, да, как было показано в этом посте. Однако я хотел бы предложить, чтобы вы оставили много шагов, и были довольно кратки в ответах «так сказано в Cdd». Я тоже не видел связи, поэтому могу понять его замешательство. John Dibling
@Mark Storer: Texas Instruments имеет серию DSP с компиляторами C ++ и 16-битным байтом. Или раньше, несколько лет назад. Есть также анахроничный зверь с 9-битным байтом, происхождение которого уходит в средние века. "Unisys"? Точно сказать не могу. Я мог бы посмотреть, если тебе действительно интересно. Ура, Cheers and hth. - Alf
@Mark Storer: Байты, которые не являются 8-битными, сегодня редки, но раньше было больше систем. Компьютер с 36-битными словами будет иметь 9-битный байт. Старые системы CDC Cyber ​​с 60-битными словами должны были бы иметь 60-битный байт (что могло бы вызвать проблемы), если бы они когда-либо получали компилятор C, но обычно символы занимали 6 бит (была 6/12-битная схема, если Вы действительно хотели строчные). David Thornley

Ваш Ответ

5   ответов
16

чтобы понять, почему именно, но вот короткая версия. Если вы сомневаетесь или сомневаетесь в этом, я советую вам прочитать всю ветку и все комментарии. В противном случае примите это как истину:

Стандарт C ++ включает в себя части стандарта C, включая определения дляLONG_MIN а такжеLONG_MAXLONG_MIN определяется как не более чем-2147483647LONG_MAX определяется как не менее+2147483647В C ++ интегральные типы хранятся в двоичном виде в базовом представленииДля того, чтобы представлять-2147483647 а также+2147483647 в двоичном коде нужно 32 бита.C ++ long гарантированно может представлять минимальный диапазонLONG_MIN черезLONG_MAX

Поэтомуlong должно быть не менее 32 бит1.

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

LONG_MIN а такжеLONG_MAX иметь значения с величинами, определяемыми стандартом C (ISO / IEC 9899: TC3) в разделе §5.2.4.2.1:

[...] их значения, определенные реализацией, должны быть равны или больше по величине [...] (абсолютное значение) показанным с тем же знаком [...]

— minimum value for an object of type long int
LONG_MIN -2147483647 // -(2 ^ 31 - 1)
— maximum value for an object of type long int
LONG_MAX +2147483647 // 2 ^ 31 - 1

1 32 бита: Это не значит, чтоsizeof (long) >= 4потому что байт не обязательно 8 бит. Согласно Стандарту, байт - это некое неопределенное (определяемое платформой) количество бит. Хотя большинство читателей сочтут это странным, есть реальное оборудование, на которомCHAR_BIT 16 или 32.

Во-вторых, и, что более важно,long будучи по крайней мере 32биты делаетне значит чтоsizeof(long) >= 4, Есть настоящие машины, для которыхCHAR_BIT 16 или 32, и, следовательно,sizeof(long) может быть всего 2 или 1. В отличие от мэйнфреймов и 9-битных миникомпьютеров, они все еще находятся в производстве AFAIK. (В основном это необычные микроконтроллеры. Да, работать с ними - это своего рода боль.) zwol
@ 6502: я включил ссылку, см. Мое редактирование. John Dibling
Стандарт С включает гарантии минимальной величины этих значений. LONG_MAX должно быть не менее +2147483647, а LONG_MIN должно быть не более -2147483647. Например, GoogleC standard minimum value of LONG_MAX если ты мне не веришь. Karl Knechtel
Меня попросили сделать ответ самостоятельно, поэтому я приму это, когда время истечет John Dibling
Есть две технические особенности, которые вы должны упомянуть. Во-первых, подписанные диапазоны симметричны (-2147483647 ... +2147483647 вместо -214748364‌‌8 ... +2147483647) чтобы учесть возможность того, что целые числа со знаком не могут использовать дополнение к двум. Самые последние стандарты C и C ++ по-прежнему считают это реалистичной возможностью, хотя последняя коммерческая машина, не являющаяся дополнением к двум, была снята с производства в 1970-х годах (одна из серий UNIVAC, точно не знаю, какая именно). (Продолжение) zwol
7

<climits> такие же, как заголовок C<limits.h> (18.2.2 в ISO C ++ 03 doc).

К сожалению, у меня нет копии стандарта C, существовавшего до C ++ 98 (т.е. C90), но в C99 (s, раздел 5.2.4.2.1),<limits.h> должен иметь как минимум это минимальные значения. Я не думаю, что это изменилось с C90, кроме C99, добавивlong long типы.

— minimum value for an object of type long int

LONG_MIN -2147483647 // −(2^31 − 1)

— maximum value for an object of type long int

LONG_MAX +2147483647 // 2^31 − 1

— maximum value for an object of type unsigned long int

ULONG_MAX 4294967295 // 2^32 − 1

— minimum value for an object of type long long int

LLONG_MIN -9223372036854775807 // −(2^63− 1)
@ Джон - Я думаю, что это обсуждение будет продолжаться в ответе MSN больше, чем в моем, поэтому я думаю, что все хорошие ответы будут там. wkl
У меня тоже нет стандарта C, (я парень C ++). Но давайте предположим, что вы разместили здесь то, что относится к C ++. Я пытаюсь соединить точки между стандартом C и стандартом C ++ и выяснить, в конечном итоге, цепочку ссылок, которые недвусмысленно говорят, что long должен быть не менее 32 бит. Давайте просто упростим это и скажем, что long должен соответствовать как минимум диапазону LONG_MIN-LONG_MAX. John Dibling
35

18.3.2 (c.limits), C: 5.2.4.2.1):

LONG_MIN -2147483647 // -(2^31 - 1)
LONG_MAX +2147483647 //   2^31 - 1

Таким образом, вы гарантированно, что long составляет не менее 32 бит.

И если вы хотите следовать по длинному окольному пути кLONG_MIN/LONG_MAX представимыlong, вы должны посмотреть на 18.3.1.2 (numeric.limits.members) в стандарте C ++:

static constexpr T min() throw(); // Equivalent to CHAR_MIN, SHRT_MIN, FLT_MIN, DBL_MIN, etc.
static constexpr T max() throw(); // Equivalent to CHAR_MAX, SHRT_MAX, FLT_MAX, DBL_MAX, etc.

Я переместил сноски в комментарий, так что это не совсем то, что указано в стандарте. Но это в основном подразумевает, чтоstd::numeric_limits<long>::min()==LONG_MIN==(long)LONG_MIN а такжеstd::numeric_limits<long>::max()==LONG_MAX==(long)LONG_MAX.

Таким образом, даже несмотря на то, что стандарт C ++ не определяет побитовое представление (подписанных) отрицательных чисел, он должен либо дополнять два, и требовать 32-битной памяти в целом, либо иметь явный знаковый бит, который означает, что он имеет 32-битной памяти также.

@ Джон, я отредактировал свой комментарий, но стандарт C ++ содержит много ссылок на стандарт ISO C. Приложение C к C ++ 03 обсуждает совместимость / несовместимость между стандартами C и C ++, и они не упоминают никаких различий между этими двумя типами по ширине типов. Это в сочетании с тем, что говорится в стандарте<climits> с тем же содержанием, что и<limits.h> (S 18.2.2) указывает мне, что ширина типов, объявленная в стандарте C, также применима к C ++. wkl
Где в стандарте C ++ сказано, чтоlong должны соответствовать значениям [LONG_MIN, LONG_MAX]? Я не могу найти такую ​​ссылку. John Dibling
Это примерно то, что вы получите, если будете следовать невероятно длинной цепочке комментариев в этом посте через все атаки ad-hominem. Приятно видеть, что это можно объяснить кратко и не называя никого именами. T.E.D.
@pst: обратите внимание, что ограничения могут быть больше, чем эти значения. Соответствующая реализация может разрешить -2 ^ 31 или + 2 ^ 31. Anon.
@Джон, Диблинг, между стандартами C и C ++ много суеты.sizes of integer types раздел из стандарта C. Даже в стандарте C ++ есть ссылки на стандарт ISO C, который был продемонстрирован «СМОТРИ ТАКЖЕ: подкласс ISO C xxx» wkl
6

стандарт C ++ явно указывает, что количество битов в байте не указано. Количество битов в long тоже не указано.

Настройканижняя граница на номер неуказав Это.

Стандарт C ++ говорит, в одном месте:

1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long).

В сущности, в другом месте говорится о включении стандарта C:

CHAR_BITS >= 8; SHORT_BITS >= 16; INT_BITS >= 16; LONG_BITS >= 32

(за исключением того, что AFAIK, идентификаторы SHORT_BITS, INT_BITS и LONG_BITS не существуют, и что эти ограничения определяются требованиями к минимальным значениям для типов.)

Это следует из того факта, что математически требуется определенное количество битов для кодирования всех значений в диапазоне (например, для длинных) LONG_MIN..LONG_MAX.

Наконец, шорты, целые и длинные должны состоять из целого числа символов; sizeof () всегда сообщает целое значение. Кроме того, перебор памяти char за char должен осуществлять доступ к каждому биту, что накладывает некоторые практические ограничения.

Эти требованияне противоречит никоим образом, Любые размеры, которые удовлетворяют требованиям, в порядке.

вно были машины с родным размером слова 36 бит. Если бы вы перенесли на них компилятор C ++, вы могли бы по закону решить, что у вас должно быть 9 битов в символе, 18 в коротком и int и 36 в длинном. Вы также можете по закону принять 36 бит в каждом из этих типов, по той же причине, по которой вы можете иметь 32 бита в int в типичной 32-битной системе сегодня. Существуют реальные реализации, которые используют 64-битные символы.

Смотрите также разделы 26.1-6 и 29.5C ++ FAQ Lite.

Правда, но мой вопрос был надолгопо крайней мере 32 бита, неименно так 32 бита John Dibling
И ответ «да, по крайней мере». По всему моему ответу значения указаны в виде нижних границ, а не точных величин (за исключениемsizeof(char)потому что, что касается C ++,char s являются байты, но байты не обязательно являются октетами). Потому что именно так их определяет Стандарт. Karl Knechtel
7

что long должен быть не менее 32 бит. Это то, что я пытаюсь установить. Стандарт C ++ явно указывает, что количество бит в байте не указано. Может быть 4, 8, 16, 42 ... Итак, как получается соединение с возможностью размещения чисел LONG_MIN-LONG_MAX до не менее 32 бит?

Вам нужно 32 бита в представлении значения, чтобы получитьпо крайней мере, так много bitpatterns. А поскольку C ++ требует двоичного представления целых чисел (об этом явно говорится в стандарте, §3.9.1 / 7), Q.E.D.

@MooingDuck: нет, в обычной арифметике нет промежуточных шагов. вопрос в том, «как осуществляется соединение», и это выглядит так: 2 ^ n = M дает непосредственно n = log2 (M). видите, промежуточного шага нет. ну, кроме случаев, когда вы хотите рассчитать его на калькуляторе без кнопки log2. тогда log2 (M) = ln (M) / ln (2). :-) Cheers and hth. - Alf
И почему вы говорите, что требуется так много битовых комбинаций? Есть много шагов, которые вы должны добавить, прежде чем написать «Q.E.D.» Mooing Duck

Похожие вопросы