2017-02-17 13 views
33

Этот вопрос задан раньше, но я все еще смущен.Имеет ли UINT_MAX все биты, установленные в 1?

Я знаю, что

unsigned int a = -1; 

UINT_MAX будет. Но это не потому, что все биты -1 установлены. С11 говорит

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

Так позволяет сказать UINT_MAX 100 (я знаю, что это должно быть больше 2^16-1, но позволяет игнорировать это сейчас)

unsigned int a = -1; // will be 
unsigned int a = -1 + UINT_MAX + 1; // 100 = UINT_MAX 

Стандарт говорит только UINT_MAX >= 2^16-1. Но скажет ли он, что это должно быть 2^n-1?

Также ответ отличается на C++?

+6

Я думаю, что стандарт в основном оставляет точное представление бит значений неопределенным (или зависит от платформы). Есть (были) некоторые действительно странные архитектуры. –

ответ

47

В C, максимальное значение для целого числа без знака должно быть в форме : 2 N - 1.

Таким образом, все значение бит значения UINT_MAX будет установлен 1. Может быть отступы, значения которых не определены.


(Цитируется: ИСО/МЭК 9899: 201x 6.2.6.2 целочисленных типов 1)
Для беззнаковых, отличных от беззнаковых символов целочисленных типов, биты представления объекта должны быть разделены на две группы, : биты значений и биты заполнения (их не должно быть ни одного). Если есть N значения бит, каждый бит должен представлять собой различную мощность 2 между 1 и 2 N -1, так что объекты этого типа должны быть способны, представляющего значение от 0 до 2 N -1 с использованием чистого двоичного представления; это должно быть известно как представление стоимости. Значения любых битов дополнений не определены.

+1

Спасибо, это очищает все. – taytay

+3

Huh. Думаю, вы не можете написать компилятор C для троичного компьютера. – Mark

+1

Ну ... вы * можете *, это просто сосать: P – MickLH

12

Нет, не совсем.

Тип без знака может состоять из битов значения и заполняющие биты.

Вы правы, что биты значения всегда будут установлены в 1 для максимального значения, но конкретные значения битов дополнений остаются в реализации. Таким образом, это означает, что UINT_MAX должно быть Номер Mersenne. Другие требования указывают, что он не может быть меньше 65535.

C и C++ эквивалентны в этом отношении.

+0

Но для U nn_MAX это должно иметь вид 2^n - 1, для некоторого n> = 16. –

+0

Действительно: это число Мерсенна (не обязательно простое), больше или равно 65535. – Bathsheba

+0

Я могу ' t найти что-либо в стандарте C++ 14 об основных типах, имеющих любые биты заполнения. Единственное, что я могу видеть, ссылаясь на стандарт C в '[basic.fundamental]', это должно уважать C 5.2.4.2.1, который является разделами пределов. – NathanOliver

2

Вы правильно сказали, что по определению преобразований -1, преобразованный в unsigned int, гарантированно будет UINT_MAX. Это не имеет никакого отношения к какому-либо битовому шаблону. Если была реализация, в которой UINT_MAX было 100, то -1, преобразованный в unsigned int, был бы равен 100.

Есть причины, по которым UINT_MAX не может быть 100: один, поскольку он должен быть ≥ 2^16-1, но это позволит UINT_MAX = 1,000,000. Во-вторых, потому, что беззнаковое целочисленное значение должно иметь двоичное представление с некоторым фиксированным числом п значений битов, поэтому UINT_MAX = 2^п - 1.

Это является возможно, что INT_MAX = 2^31 - 1 и UINT_MAX = 2^31 - 1 (не 2^32 - 1, как это обычно бывает). В этом случае -1 будет иметь 32 бита; -1 cast to unsigned int будет 2^31 - 1 и будет иметь только 31 бит.

+0

Tiny nitpick: -1 в 1 + 31-битном 'подписанном int' имеет 32 бита set _if для реализации используется дополнение two_, которое практически все машины с середины 80-х годов делают для целых чисел, но дополнение 6.2.6.2p2 _allows_ ones или знака и величины, которая имела бы 31 бит и 2 бит соответственно. –

+0

@ dave_thompson_085: Система с 32-битным значащим знаком с двумя символами почти наверняка имела бы 32-разрядное целое число без знака. Примерно только по той причине, что у неконкурентоспособной реализации будет «неподписанный» тип с меньшим количеством возможных значений, чем соответствующий тип подписки, будет заключаться в том, что аппаратное обеспечение было ограничено формой подписанной арифметики, которая не могла учитывать двухзначных значений. – supercat