Как определить, является ли Int 16-битным

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

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

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

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

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

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

Обновлено: я забыл упомянуть, что условное утверждение также запрещено. Так что никаких ifs, elses, циклов и т.д.

!0x0 == 1...!0x0 + !0x0 == 2...просто говорю :)
pmg 30.01.2019 23:47

@pmg ааааааааааааааааааааааааааааааааааааааааааааааааааа, я улавливаю твой дрейф

user10992941 30.01.2019 23:49

Прежде всего, знаете ли вы размер int и размер short для вашей архитектуры/компилятора? Предполагая, что sizeof(int) == sizeof(int32_t) и sizeof(short) == sizeof(int16_t) - это большое предположение.

alx 31.01.2019 02:09
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
915
3

Ответы 3

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

 (unsigned)~0 == 0xffff

или без ==

 !((unsigned)~0 - 0xffff)

 !((unsigned)~0 ^ 0xffff)

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

!((unsigned)~0 ^ (((0xff << (!!0xff << !!0xff << !!0xff << !!0xff))) | 0xff)))

Я как бы понимаю, что вы делаете, но зачем добавлять два оператора ! рядом с каждым 0xff? Не будет ли это просто отрицанием отрицания? Кроме того, я должен использовать максимум 8 операторов.

user10992941 31.01.2019 00:12

Мне нужен номер 1. !! преобразует любое ненулевое значение в 1.

0___________ 31.01.2019 00:14

затем 3-е решение. Другого пути нет

0___________ 31.01.2019 00:16

@P__J__ подержите мое пиво ;-)

deamentiaemundi 31.01.2019 00:37

Для удобочитаемости установите 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.

Решение основано на том факте, что 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 операций!

Мне нравится ваша логика, и ваш ответ очень четкий и лаконичный, но как мне это сделать без использования оператора -? Кроме того, мне разрешено использовать только 8 операторов.

user10992941 31.01.2019 04:57

Я пропустил тот факт, что "-" было запрещено. Но единственная требуемая операция — это «-1», и ее можно заменить на +(~0). По количеству операторов подходит, но не с ванлайнером. Я обновляю ответ.

Alain Merigot 31.01.2019 07:56

@vastImmortalSuns В предыдущем ответе была ошибка, но я нашел гораздо более простой способ, полностью учитывающий ограничения.

Alain Merigot 31.01.2019 13:31

Ах я вижу! Спасибо, что прояснили это, я не знал, что вы можете даже отрицать 0, но теперь это имеет смысл :)

user10992941 31.01.2019 20:44

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