问题
I'm trying to recreate this function:
int test(int x) {
int i;
for (i = 0; i < 32; i+=2)
if ((x & (1<<i)) == 0)
return 0;
return 1;
}
But only using these bit-wise operators: !, ~, &, ^, |, +, <<, and >> (Meaning no loops or if statements either)
I am so confused with this question I have been staring at it for like a hour and am still not sure where to start.
I understand that basically it is taking x comparing it with 2^i where i is 0-31 and then returning 0 if x and 2^i do not share any of the same bits and returning 1 otherwise.
But I feel like there is a more simple, non-bit focused explanation that summarizes this better and if someone could even just give me that it would be a huge help.
回答1:
It is not clear what the question is here but from:
But I feel like there is a more simple, non-bit focused explanation that summarizes this better and if someone could even just give me that it would be a huge help.
It seems you are simply asking for a description of what the code does. That being the case, your stated understanding is entirely incorrect. The behaviour of the code is simply:
- Return 1 if all even numbered bits are 1, and zero otherwise.
回答2:
As has already been stated, the minimal solution would be
return (x & 0x55555555) == 0x55555555 ;
However, this uses '==', which is not in the list of allowed operators. Comparisons of integers is more or less equivalent to seeing if the difference between the numbers is zero or not, but '-' is also not in the list of allowed operators, but '+' is. Setting the first bit in a signed integer is equivalent to making it negative and subtracting 1. Therefore, the function can be written as:
return !(((x & 0x55555555) | 0x80000000) + 0x55555556);
This assumes the input is not negative, and it also seems to fail for very large input, but works for numbers in the range 0 to 1431655764 in my tests. Also, this assumes 32-bit integers.
Edit: The XOR operator is obviously a much better substitute for '==':
return !((x & 0x55555555) ^ 0x55555555);
Works for negative numbers too!
回答3:
I think we are in the same, or similar classes :). However if that is true make sure to remember that any numbers you use would need to be below 0xff. So 0x55555555 would need to be (0x55 << 24) | (0x55 << 16) | (0x55 << 8) | 0x55) (although there is probably a better way to do this).
I have the same question, but I also have the variant:
int testdl4(int x) {
int i;
for (i = 1; i < 32; i+=2)
if ((x & (1<<i)) == 0)
return 0;
return 1;
}
How would starting with a 1 instead of a 0 for i change the 3rd answer given by @Johnny Johansson? (Same bit-wise limitations)
回答4:
This seems to be testing negative numbers to see if they & with the powers of every other 2
def testit(x):
print ( bin(x), test(x))
def test(x):
for i in range (0, 32, 2):
if ((x & (1<<i))) == 0:
print(x, bin(x), bin(1<<i))
print("{} & {} ({}) is 0".format(x, 1<<i))
return 0
print(x, bin(x), ((x & (1<<i))), bin(((x & (1<<i)))))
return 1
In [494]: testit(-2)
-2 -0b10 0b1
-2 & 1 is 0
-0b10 0
In [495]: testit(-3)
-3 -0b11 1073741824 0b1000000000000000000000000000000
-0b11 1
In [496]: testit(-4)
-4 -0b100 0b1
-4 & 1 is 0
-0b100 0
In [497]: testit(-5)
-5 -0b101 0b100
-5 & 4 is 0
-0b101 0
In [498]: testit(-6)
-6 -0b110 0b1
-6 & 1 is 0
-0b110 0
In [499]: testit(-7)
-7 -0b111 0b100
-7 & 4 is 0
-0b111 0
In [500]: testit(-8)
-8 -0b1000 0b1
-8 & 1 is 0
-0b1000 0
In [501]: testit(-9)
-9 -0b1001 1073741824 0b1000000000000000000000000000000
-0b1001 1
In [508]: testit(-17)
-17 -0b10001 0b10000
-17 & 16 is 0
-0b10001 0
In [515]: testit(-203)
-203 -0b11001011 0b1000000
-203 & 64 is 0
-0b11001011 0
The above output shows that every other powers of two number that & with your negative number will be 0, if not it quits checking at powers of two of 1073741824. Does this help?
回答5:
If you're looking to see if numbers share the same bitlength's you can use this:
def log2_floor(x):
res=-1
while x:
res+=1
x = x>>1
return res
def compare_bitlength(hm, hm2):
hmone = log2_floor(hm)
hmtwo = log2_floor(hm2)
if hmone == hmtwo:
print (f'{hm} and {hm2} share the same bitlength of {hmone}')
else:
print (f'{hm} has bitlength {hmone} and {hm2} has bitlength {hmtwo} and are not the same bitlength')
In [351]: compare_bitlength(15,14)
15 and 14 share the same bitlength of 3
来源:https://stackoverflow.com/questions/58655811/checking-bits-of-ints-to-see-if-they-share-binary-with-the-power-of-2-bitwise-o