У меня много кода, который выполняет побитовые операции над целыми числами без знака. Я написал свой код с предположением, что эти операции выполняются с целыми числами фиксированной ширины без каких-либо дополнительных битов. Например, массив 32-разрядных целых чисел без знака, из которых все 32 бита доступны для каждого целого числа.
Я пытаюсь сделать мой код более переносимым и хочу убедиться, что я C89-совместим (в данном случае). Одна из проблем, с которыми я сталкивался, - это возможные дополненные целые числа. Возьмите этот крайний пример из руководства GMP :
Однако в векторных системах Cray можно заметить, что short и int всегда хранятся в 8 байтах (и это указывает sizeof
), но используют только 32 или 46 бит. Признак гвоздей может объяснить это, передав, например, 8*sizeof(int)-INT_BIT
.
Я также читал об этом типе заполнения в других местах. Я на самом деле читал пост на SO вчера вечером (извините, у меня нет ссылки, и я собираюсь процитировать что-то похожее из памяти), где, если у вас есть, скажем, двойной с 60 используемыми битами, остальные 4 могли бы использоваться для заполнения, и эти биты заполнения могут служить некоторым внутренним целям, поэтому они не могут быть изменены.
Так скажем, например, мой код скомпилирован на платформе, где тип unsigned int имеет размер 4 байта, каждый байт составляет 8 бит, однако наиболее значимые 2 бита являются битами заполнения. Будет ли UINT_MAX
в этом случае 0x3FFFFFFF (1073741823)?
#include <stdio.h>
#include <stdlib.h>
/* padding bits represented by underscores */
int main( int argc, char **argv )
{
unsigned int a = 0x2AAAAAAA; /* __101010101010101010101010101010 */
unsigned int b = 0x15555555; /* __010101010101010101010101010101 */
unsigned int c = a ^ b; /* ?? __111111111111111111111111111111 */
unsigned int d = c << 5; /* ?? __111111111111111111111111100000 */
unsigned int e = d >> 5; /* ?? __000001111111111111111111111111 */
printf( "a: %X\nb: %X\nc: %X\nd: %X\ne: %X\n", a, b, c, d, e );
return 0;
}
- Безопасно ли XOR два целых числа с битами заполнения?
- Разве я не сделал бы XOR какими-либо битами заполнения?
Я не могу найти это поведение в C89.
Кроме того, гарантируется, что переменная c
будет 0x3FFFFFFF
или если, например, оба бита заполнения были включены в a или b, то c
будет 0xFFFFFFFF
?
Тот же вопрос с d
и e
. Я управляю битами заполнения, сдвигая?
Я ожидаю увидеть это ниже, предполагая, что 32 бита с двумя старшими значащими битами, используемыми для заполнения, но я хочу знать, гарантировано ли что-то подобное:
a: 2AAAAAAA
b: 15555555
c: 3FFFFFFF
d: 3FFFFFE0
e: 01FFFFFF
Кроме того, биты заполнения всегда являются старшими значащими битами или они могут быть младшими значащими битами?
РЕДАКТИРОВАТЬ 19/12/2010 17:00 EST : Кристоф ответил на мой вопрос. Спасибо!
Я также спросил (выше), всегда ли биты заполнения являются наиболее значимыми битами. Это приводится в обосновании стандарта C99, и ответ - нет. Я играю безопасно и предполагаю то же самое для C89. Вот, в частности, что говорит обоснование C99 для §6.2.6.2 (Представление целочисленных типов):
Биты заполнения доступны для пользователя в виде целого числа без знака. Например, предположим, что машина использует пару 16-битных шорт (каждая со своим собственным знаковым битом) для создания 32-битного целого числа, а знаковый бит нижнего короткого замыкания игнорируется при использовании в этом 32-битном целом. Затем, как 32-разрядное знаковое целое, существует бит дополнения (в середине 32-разрядного), который игнорируется при определении значения 32-разрядного знакового целого. Но если этот 32-битный элемент обрабатывается как 32-битное беззнаковое целое, то этот бит дополнения виден программе пользователя. Комитету C сказали, что есть машина, которая работает таким образом, и это одна из причин, по которой биты заполнения были добавлены в C99.
В сносках 44 и 45 упоминается, что биты четности могут быть битами заполнения. Комитет не знает ни о каких машинах с доступными для пользователя битами четности в целом числе. Поэтому комитет не знает ни о каких машинах, которые обрабатывают биты четности как биты заполнения.
РЕДАКТИРОВАТЬ 28/12/2010 15:00 EST : я нашел интересное обсуждение на comp.lang.c несколько месяцев назад.
Одно замечание Дитмара, которое мне показалось интересным:
Отметим, что биты заполнения не являются необходимыми для существования представлений ловушек;комбинации битов значения, которые не представляют значение типа объекта, также подойдут.