简体   繁体   中英

Return 1 if any bits in an integer equal 1 using bit operations in C

I've been thinking about this problem for hours. Here it is:

Write an expression that returns 1 if a given integer "x" has any bits equal to 1. return 0 otherwise.

I understand that I'm essentially just trying to figure out if x == 0 because that is the only int that has no 1 bits, but I can't figure out a solution. You may not use traditional control structures. You may use bitwise operators, addition, subtraction, and bit shifts. Suggestions?

Here's the best I could come up with:

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

where BITS = 32 for 32 bit ints, ie BITS = sizeof(int) * CHAR_BIT;

Here's a test program:

#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;
}

Using !!x will give you the right answer. Since !0 = 1 and !(any nonzero number) = 0.

分别屏蔽每个位,将它们全部向下移动到lsb位置,或者将它们一起移位。

对于32位值,以下内容适用于所有位模式。

return (a | -a) >> 31;

How about !(x&&~x)&&x ?

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

It seems work, but I'm not sure when overflow happens.

0 || number - this will return 0 only if the number is 0 and will return 1 if the number is any other number than 0. Since a number without any bit as 1 will be equal to 0, we need to check it with 0.

You could just cast your int to a bool . But I doubt that's the purpose of your homework ;-)

int any_bits_to_one(unsigned int n) {
  int result = 0, i;

  for (i=0; !result && i < sizeof(unsigned int) * 8; i++)
    result |= (n & (1<<i)) ? 1 : 0;

  return result;
}

For 32 bit integers

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;
}

untested, that's the first thing that came to my mind:

 while(n & pow(2, e) == 0 && e++ <= 16) ;  // 16 or 32

if e == 16 after the loop n is 0.

Bitwise AND with 0 and any number must equal zero, but the only foolproof test would be with 0xFFFF, or every bit being set. To get all bits set, you should have a signed int, and assign it -1. You will then have an int with all bits set to 1, regardless of size.

So my answer would be to bitwise AND it with -1

I believe this is the simplest way.

return !!(0|x);

The only time your x will not have a 1 in it is when all bits are 0, or x == 0. So 0|0 -> 0 else 0|x -> non zero.

In C language, any value other than ZERO (either positive or negative) is treated as TRUE. And there should be a condition to check either your question's solution returns a ZERO or ONE (or other than ZERO). Therefore this answer is perfectly as per your requirement. This uses only bit-wise operators.

return (x & 0xFFFF);

This line returns ZERO when neither of any bit in "x" is 1, and returns Non-Zero (TRUE in a sense) when any of the bit is 1 in "x".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM