Является ли неотрицательный диапазон целого числа со знаком C ++ по крайней мере таким же большим, как и отрицательный диапазон?

Соответствует ли стандарт C ++ тому, что неотрицательное диапазон стандартного целочисленного типа со знаком, по крайней мере, такой же большой, как и отрицательный диапазон?

РЕДАКТИРОВАТЬ: Обратите внимание, что я имею в виду неотрицательное Диапазон здесь, а не положительный диапазон, который, очевидно, на один меньше, чем неотрицательное спектр.

РЕДАКТИРОВАТЬ: Если мы предположим, C ++ 11, ответ «Да». Смотрите мои разъяснения ниже. С точки зрения C ++ 03 ответ, вероятно, «Нет».

Тот же вопрос можно задать следующим образом: гарантирует ли стандарт, что результат a - b представимо в стандартном целочисленном типе со знаком T при условии, что оба a а также b являются отрицательный значения типа Tи что a ≥ b?

Я знаю, что стандарт допускает представление отрицательных значений в виде дополнения до двух, дополнения до единицы и знаковой величины (см. C ++ 11, раздел 3.9.1 [basic.fundamental], пункт 7), но я не уверен, требует ли оно использования одного из этих трех представлений. Возможно нет.

Если мы примем одно из этих трех представлений и предположим, что нет никаких «ложных» ограничений ни в одном из двух диапазонов (отрицательном и неотрицательном), то действительно верно, что неотрицательный диапазон по меньшей мере равен большой, как отрицательный. Фактически, с дополнением до двух размер двух диапазонов будет равен, а с двумя другими представлениями размер неотрицательного диапазона будет на один больше, чем размер отрицательного.

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

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

Любая помощь будет оценена.


Обратите внимание, что было бы достаточно чего-то подобного: Каждый бит в «слоте памяти» целого числа имеет одну и только одну из следующих функций:

  • неиспользуемый
  • Знаковый бит (исключительно или смешанный бит знак / значение)
  • Бит значения (участвует в значении)

У меня смутное воспоминание о том, что C99 что-то говорит в том же духе. Кто-нибудь знает что-нибудь об этом?


Хорошо, C99 (с TC3) предоставляет необходимые гарантии в разделе 6.2.6.2 «Целочисленные типы» параграфа 2:

Для целочисленных типов со знаком биты представления объекта должны быть разделены на три группы: биты значения, биты заполнения и бит знака. Там не должно быть никаких битов заполнения; должен быть ровно один знаковый бит. Каждый бит, который является битом значения, должен иметь то же значение, что и тот же бит в представлении объекта соответствующего типа без знака (если имеется M битов значения в типе со знаком и N в типе без знака, то M ≤ N). Если бит знака равен нулю, он не должен влиять на результирующее значение. Если бит знака равен единице, значение должно быть изменено одним из следующих способов:

  • соответствующее значение со знаком бит 0 обнуляется (знак и величина);
  • знаковый бит имеет значение — (2N ) (два дополнения);
  • знаковый бит имеет значение — (2N — 1) (дополняют).

Что из этого применимо, определяется реализацией, как и то, является ли значение с знаковым битом 1 и всеми битами значения ноль (для первых двух) или со знаковым битом и всеми битами значения 1 (для дополнения единиц) представлением ловушки или нормальное значение. В случае знака, величины и их дополнения, если это представление является нормальным значением, оно называется отрицательным нулем.

Может кто-нибудь подтвердить, что эта часть C99 также является обязательной частью C ++ 11?


Я еще раз внимательно посмотрел как на стандарты C99, так и на стандарты C ++ 11, и стало ясно, что гарантии в параграфе 2 раздела 6.2.6.2 C99 также являются обязательными в C ++ 11.

C89 / C90 не дает таких же гарантий, поэтому нам нужен C99, что означает, что нам нужен C ++ 11.

Таким образом, C ++ 11 (и C99) предоставляет следующие гарантии:

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

  2. Размер неотрицательное диапазон один больше или равно размеру отрицательного диапазона для всех основных целых типов со знаком (стандарт + расширенный).

Вторая гарантия может быть пересчитана следующим образом:

-1 ≤ min<T> + max<T> ≤ 0

для любого основного целого типа со знаком T (стандарт + расширенный) где min<T> а также max<T> являются сокращением для std::numeric_limits<T>::min() а также std::numeric_limits<T>::max() соответственно.

Кроме того, если мы предположим, что a а также b являются значениями того же самого или различных фундаментальных целочисленных типов со знаком (стандартные или расширенные), тогда следует, что a - b хорошо определен и представлен в decltype(a - b) пока a а также b либо оба отрицательны, либо оба неотрицательны.

4

Решение

Стандарт, кажется, не требует такой вещи, хотя я могу пропустить ключевые места. Все, что мы знаем о фундаментальных знаковых целочисленных типах, находится в 3.9.1 / 2:

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

И в 3.9.1 / 7:

Типы bool, char, char16_t, char32_t, wchar_t, а также подписанные и
целочисленные типы без знака вместе называются целочисленными типами.48 A
синонимом целочисленного типа является целочисленный тип. Представления
целочисленные типы должны определять значения с использованием чистой двоичной нумерации
система.

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

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]