简体   繁体   English

比较“if between”与按位运算符而不是逻辑运算符

[英]Compare “if between” with bitwise operators instead of logical

Okay i know this is a pretty mean task from which i got nightmares but maybe ..i'll crack that code thanks to someone of you. 好吧,我知道这是一个非常卑鄙的任务,我从中做了噩梦,但也许..我会破解那些代码感谢你们。

I want to compare if number is between 0 and 10 with bitwise operators. 我想用比特运算符比较数字是否在0到10之间。 Thats the thing.. it is between 0 and 10 and not for example between 0 and 2, 0 and 4, 0 and 8 and so on.. 那东西..它在0到10之间,而不是例如在0和2,0和4,0和8之间等等。

Reference for number/binary representation with 0-4 bits. 带有0-4位的数字/二进制表示的参考。 (little endian) (小端)

0 0 0 0

1 1 1 1

2 10 2 10

3 11 3 11

4 100 4 100

5 101 5 101

6 110 6 110

7 111 7 111

8 1000 8 1000

9 1001 9 1001

10 1010 10 1010


11 1011 11 1011

12 1100 12 1100

13 1101 13 1101

14 1110 14 1110

15 1111 15 1111


Trying to figure out something like if(((var & 4) >> var) + (var & 10)) 试图找出if(((var&4)>> var)+(var&10)之类的东西

I attempt to solve it with bitwise operators only ( no addition ). 我尝试仅使用按位运算符( 无添加 )来解决它。

The expression below will evaulate to nonzero if the number ( v ) is out of the 0 - 10 inclusive range: 如果数字( v )超出0-10范围,则下面的表达式将变为非零:

(v & (~0xFU)) |
( ((v >> 3) & 1U) & ((v >> 2) & 1U) ) |
( ((v >> 3) & 1U) & ((v >> 1) & 1U) & (v & 1U) )

The first line is nonzero if the number is above 15 (any higher bit than the first four is set). 如果数字大于15(第一行高于设置的前四位),则第一行非零。 The second line is nonzero if in the low 4 bits it is between 12 and 15 inclusive. 如果在低4位中它在12和15之间,则第二行是非零的。 The third line is nonzero if in the low 4 bits the number is either 11 or 15. 如果在低4位中数字为11或15,则第三行非零。

It was not clear in the question, but if the number to test is limited between the 0 - 15 inclusive range (only low 4 bits), then something nicer is possible here: 在问题中不清楚,但如果要测试的数量限制在0到15之间的范围(只有低4位),那么这里有更好的东西:

  ((~(v >> 3)) & 1U) |
( ((~(v >> 2)) & 1U) & (( ~v      ) & 1U) ) |
( ((~(v >> 2)) & 1U) & ((~(v >> 1)) & 1U) )

First line is 1 if the number is between 0 and 7 inclusive. 如果数字介于0和7之间,则第一行为1。 Second line is 1 if the number is one of 0, 2, 8 or 10. Third line is 1 if the number is one of 0, 1, 8 or 9. So OR combined the expression is 1 if the number is between 0 and 10 inclusive. 如果数字是0,2,8或10中的一个,则第二行是1.如果数字是0,1,8或9中的一个,则第三行是1.因此如果数字在0和0之间,则表达式为OR 10个包含。 Relating this solution, you may also check out the Karnaugh map , which can assist in generating these (and can also be used to prove there is no simpler solution here). 关于这个解决方案,你也可以查看卡诺图 ,它可以帮助生成这些(也可以用来证明这里没有更简单的解决方案)。

I don't think I could get any closer stricly using only bitwise operators in a reasonable manner. 我认为我不能以合理的方式严格使用按位运算符 However if you can use addition it becomes a lot simpler as Pat's solution shows it. 但是,如果您可以使用添加,那么随着Pat的解决方案显示它会变得更加简单。

Assuming that addition is allowed, then: 假设允许添加,则:

(v & ~0xf) | ((v+5) & ~0xf)

is non-zero if v is out-of-range. 如果v超出范围,则非零。 The first term tests if v is outside the range 0..15, and the second shifts the unwanted 11, 12, 13, 14, 15 outside the 0..15 range. 第一项测试v是否在0..15范围之外,第二项测试不需要的11, 12, 13, 14, 15在0..15范围之外。

When addition is allowed and the range is 0..15, a simple solution is 当允许添加并且范围是0..15时,一个简单的解决方案是

(v - 11) & ~7

which is nonzero when v is in the range 0..10. 当v在0..10范围内时,它是非零的。 Using shifts instead, you can use 改为使用轮班,你可以使用

(1<<10) >> v

which is also nonzero if the input is in the range 0..10. 如果输入在0..10范围内,这也是非零值。 If the input range is unrestricted and the shift count is modulo 32, like on most CPUs, you can use 如果输入范围不受限制且移位计数为模32,就像在大多数CPU上一样,您可以使用

((1<<11) << ~v) | (v & ~15)

which is nonzero if the input is not in the range (the opposite is difficult since already v == 0 is difficult with only bitops). 如果输入不在范围内,那么它是非零的(相反的情况很难,因为只有bitops很难用v == 0)。 If other arithmetic operations are allowed, then 如果允许其他算术运算,那么

v / 11

can be used, which is also nonzero if the input is not in the range. 可以使用,如果输入不在范围内,它也是非零的。

bool b1 = CheckCycleStateWithinRange(cycleState, 0b0, 0b1010); // Note *: 0b0 = 0 and 1010 = 10

bool CheckCycleStateWithinRange(int cycleState, int minRange, int maxRange) const
{
   return ((IsGreaterThanEqual(cycleState, minRange) && IsLessThanEqual(cycleState, maxRange)) ? true : false );
}

int IsGreaterThanEqual(int cycleState, int limit) const
{
   return ((limit + (~cycleState + 1)) >> 31 & 1) | (!(cycleState ^ limit));
}

int IsLessThanEqual(int cycleState, int limit) const
{
   return !((limit + (~cycleState + 1)) >> 31 & 1) | (!(cycleState ^ limit));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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