Как определить, является ли Int 16 битами - PullRequest
0 голосов
/ 31 января 2019

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

Мне нужно определить, является ли целое число x может уместиться в короткую.Я ограничен использованием операторов ! ~ & ^ | + << >>.Кроме того, я могу использовать только до 8 из этих операторов.

Я знаю из нескольких других постов (вроде этого: Как определить, может ли 32-битное целое число соответствовать 16-битному короткому ), что решение типа

!(((((x) & 0xffff8000) >> 15) + 1) & 0x1fffe)

будет работать нормально (кредит Эмилю Романусу).Однако мне также запрещено использовать любые константы, отличные от 0x0 и 0xff.

Я в основном запутался в логике здесь.Любые идеи?

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

Ответы [ 3 ]

0 голосов
/ 31 января 2019

Для набора читаемости invuint = ~0u и invushort = ~((short)0u), чем мы можем сделать invuint - invushort, что либо 0, либо нет0 в стандартном C равно false, поэтому вы можете просто с помощью !(invuint - invushort) увидеть, подходит ли unsigned int к unsigned short.

Но это, скорее всего, не то, что выпопросили сделать, это было бы слишком легко.Если вам нужно знать, подходит ли содержимое unsigned int к unsigned short, это немного усложняется.

Мы можем использовать incushort = ~((short)0u) здесь как маску.

С an_uint = 0; an_uint = incushort мы устанавливаем младшие биты an_uint в единицы, поэтому у нас 0x0000ffff.Если перевернуть это с ~an_uint, вы получите 0xXXXX0000, где X означает неизвестное количество единиц.Поэтому, если sizeof(unsigned int) == sizeof(unsigned short), мы получим 0, но мы могли бы сделать это проще, см. Выше.

Если мы используем mask = 0xXXXX0000 в качестве маски, чтобы получить все биты, которые больше unsigned short с uint_with_unknown_content & mask мы получаем 0, если uint_with_unknown_content вписывается в unsigned short.

0 голосов
/ 31 января 2019

Решение основано на том факте, что x^(x<<1) будет иметь свои 16 MSB в нуле, если 17 MSB из x все равны и x могут быть закодированы в 16 битах.

Следовательно

return (x^(x<<1))&(0xffff0000)==0;

решает проблему.

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

int canNOTbemappedto16bits(int x) {
   int one = !0x0;  // 1 op
   int ffff = (unsigned short) ~0x0;//1 op
   int ffff0000 = (unsigned int) ~0x0 ^ ffff; // 2ops
   return   (x^(x<<one))&ffff0000 ; // 3ops
}

7 операций!

0 голосов
/ 31 января 2019

это ваше решение

 (unsigned)~0 == 0xffff

или без ==

 !((unsigned)~0 - 0xffff)

 !((unsigned)~0 ^ 0xffff)

или если разрешен только 0xff

!((unsigned)~0 ^ (((0xff << (!!0xff << !!0xff << !!0xff << !!0xff))) | 0xff)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...