Возвращает 1, если любые биты в целом числе равны 1, используя битовые операции в C - PullRequest
7 голосов
/ 08 февраля 2011

Я думал об этой проблеме часами. Вот оно:

Напишите выражение, которое возвращает 1, если данное целое число "x" имеет биты, равные 1. В противном случае возвращает 0.

Я понимаю, что, по сути, я просто пытаюсь выяснить, если x == 0, потому что это единственный int, у которого нет 1 бита, но я не могу найти решение. Вы не можете использовать традиционные структуры управления. Вы можете использовать побитовые операторы, сложение, вычитание и сдвиги битов. Предложения?

Ответы [ 13 ]

3 голосов
/ 08 февраля 2011

Вот лучшее, что я мог придумать:

y = (((-x) | x) >> (BITS - 1)) & 1;

, где BITS = 32 для 32-битных, т. Е. BITS = sizeof(int) * CHAR_BIT;

Вот тестовая программа:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int main(int argc, char *argv[])
{
    const int BITS = sizeof(int) * CHAR_BIT;

    if (argc == 2)
    {
        int x = atoi(argv[1]);
        int y = (((-x) | x) >> (BITS - 1)) & 1;

        printf("%d -> %d\n", x, y);
    }

    return 0;
}
2 голосов
/ 12 февраля 2015

Использование !! x даст вам правильный ответ. Так как! 0 = 1 и! (Любое ненулевое число) = 0.

1 голос
/ 08 февраля 2011

Для 32-битного значения следующее будет работать для всех битовых комбинаций.

return (a | -a) >> 31;
1 голос
/ 08 февраля 2011

Маскируйте каждый бит отдельно, сдвиньте их все в положение lsb и / или их вместе.

0 голосов
/ 24 июля 2015

В языке C любое значение, кроме ZERO (положительное или отрицательное), рассматривается как ИСТИНА.И должно быть условие проверить, что решение вашего вопроса возвращает НОЛЬ или ОДИН (или не НОЛЬ).Поэтому этот ответ идеально соответствует вашему требованию.При этом используются только побитовые операторы.

return (x & 0xFFFF);

Эта строка возвращает ноль, если ни один из битов в «x» не равен 1, и возвращает ненулевой (ИСТИНА в некотором смысле), когда любой бит1 в «х».

0 голосов
/ 01 апреля 2015

Я считаю, что это самый простой способ.

return !!(0|x);

Единственный раз, когда у вашего x не будет 1, это когда все биты равны 0 или x == 0. Так что 0 | 0 -> 0 иначе 0 | x -> не ноль.

0 голосов
/ 22 января 2014

0 ||число - это вернет 0, только если число равно 0, и вернет 1, если число любое другое число, отличное от 0. Поскольку число без какого-либо бита, равного 1, будет равно 0, нам необходимо проверить его с 0.

0 голосов
/ 21 октября 2013

Как насчет! (X && ~ x) && x?

#include <stdio.h>
void main(){
  int x;
  scanf("%d",&x);
  printf("%d\n",(!(x&&~x)&&x));
}

Кажется, это работает, но я не уверен, когда произойдет переполнение.

0 голосов
/ 08 февраля 2011

Побитовое И с 0 и любое число должно равняться нулю, но единственный надежный тест будет с 0xFFFF или с каждым установленным битом. Чтобы получить все установленные биты, вы должны иметь int со знаком и присвоить ему -1. Затем у вас будет int со всеми битами, установленными в 1, независимо от размера.

Так что мой ответ будет побитовым И это с -1

0 голосов
/ 08 февраля 2011

Для 32-битных целых чисел

int return_not_zero(int v)
{
  r=v;
  r=(r&0xFFFF) | (r>>16); 
  r=(r&0xFF) | (r>>8);
  r=(r&0x0F) | (r>>4);
  r=(r&0x03) | (r>>2); 
  r=(r&0x01) | (r>>1); 
  return r;
}
...