C++ и неподписанные типы

Я читаю C++ Primer 5th Edition и не понимаю следующую часть:

В типе без знака все биты представляют значение. Например, 8-разрядный символ без знака может содержать значения от 0 до 255 включительно.

Что значит "все биты представляют значение"?

5 ответов

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

Значение объекта тривиально копируемого типа определяется некоторыми битами в нем, в то время как другие биты не влияют на его значение. В стандарте C++ биты, которые не влияют на значение, называются битами заполнения.

Например, рассмотрим тип с 8 битами, где последние 4 бита являются битами заполнения, тогда объекты, представленные 00000000 и 00001111, имеют одинаковое значение и сравниваются равными.

В действительности биты заполнения часто используются для выравнивания и / или обнаружения ошибок.

Зная знания выше, вы можете понять, что говорится в книге. Это говорит, что нет никаких битов заполнения для беззнакового типа. Однако утверждение неверно. На самом деле, стандарт гарантирует только unsigned char (а также signed char, char) не имеет битов заполнения. Ниже приводится цитата из связанной части стандарта [basic.fundamental] / 1:

Для узких типов символов все биты представления объекта участвуют в представлении значения.

Также в стандарте C11 6.2.6.2/1 говорится

Для целочисленных типов без знака, отличных от знака без знака, биты представления объекта должны быть разделены на две группы: биты значения и биты заполнения (не должно быть ни одного из последних).

Это означает, что все 8 битов представляют фактическое значение, в то время как в знаковых символах только 7 битов представляют фактическое значение, а 8-й бит (самый значимый) представляет знак этого значения - положительный или отрицательный (+/-).

Это в основном теоретическая вещь. На реальном оборудовании то же самое верно для signed целые числа также. Очевидно, что со знаком целых чисел некоторые из этих значений являются отрицательными.

Вернуться к unsigned - текст в основном говорит о том, что значение числа без знака просто 1<<0 + 1<<1 + 1<<2 + ... до общего количества битов. Важно, что не только все биты вносят свой вклад, но и все комбинации битов образуют действительное число. Это не так для signed целые числа. Поэтому, если вам нужна битовая маска, она должна быть unsigned тип достаточной ширины, или вы можете столкнуться с недопустимыми битовыми комбинациями.

Например, один байт содержит 8 битов, а все 8 битов используются для отсчета от 0.

Для без знака все биты ноль = 00000000 означают 0, 00000001 = 1, 00000010 = 2, 00000011 = 3, ... до 11111111 = 255.
Для подписанного байта (или знакового символа) крайний левый бит означает знак и, следовательно, не может использоваться для подсчета. (Я оптически разделяю крайний левый бит!) 0 0000001 = 1, но 1 0000001 = -1, 0 0000010 = 2 и 1 0000010 = -2 и т. Д. До 0 1111111 = 127 и 1 1111111 = -127. В этом примере 1 0000000 будет означать -0, что бесполезно / потрачено впустую, поэтому это может означать, например, 128.

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

Другие вопросы по тегам