使用C中的按位运算符查找值是否在某个范围内

时间:2017-02-06 21:34:24

标签: c binary bit-manipulation bitwise-operators twos-complement

所以我正在研究这种方法,但仅限于使用这些运算符:

<<,>>,!,〜,&,^,|,+

我需要找出给定的int参数是否可以在给定的位数中使用2的补码算法来表示。

这是我到目前为止所做的:

int validRange(int val, int bits){
    int minInRange = ~(1<<(bits + ~0 ))+1;   //the smallest 2's comp value possible with this many bits
    int maxInRange = (1<<(bits+~0))+~0;  //largest 2's comp value possible 
    ..........
}

这是我到目前为止所做的,现在我需要做的就是弄清楚如何判断minInRange&lt; = val&lt; = maxInRange。我希望我可以使用大于或小于运算符,但我们不被允许。检查这个的按位方法是什么?

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

两位补码负数的高位始终为'1'。

您可以通过转换为FF - >转换为从负转换为正(反之亦然) 00 - &gt; 01.也就是说,反转位,加1.(01 - &gt; FE - &gt; FF也可以工作:反转位,加1)

如果数字中的最高设置位在您的范围内,则可以表示正数。 (nbits - 8位有符号字符的1:7位等)

我不确定你的约束是否允许你使用数组。他们会加速一些事情,但可以用循环或if语句替换。

无论如何,如果1&lt;&lt; (NUM_INT_BITS-1)在您的输入上设置,然后是负数。 反转,添加一个。

现在,考虑0.零是一个常数,无论多少位,它总是相同的。但是如果你反转0,你会得到“所有位”,这些位会因架构而改变。所以,ALL_BITS = ~0。

如果您想知道正数是否可以用2位表示,请检查是否设置了大于或等于位2的位。例如:

two_bits = 0b00000011
any_other_bits = ~two_bits # Result: 0b11...11100
if positive_number & any_other_bits
    this number is too fat for these bits!

但是你怎么知道~two_bits应该是什么?嗯,这是“除了底部之外的所有设置位 - 很多”。你可以通过以“所有设置位”开始并将它们向上移动(也称为“左”)来构造它,但是很多地方:

any_other_bits = ~0 << 2  # where "2" is the number of bits to check

现在一起:

if (val & ((unsigned)INT_MAX + 1))
    val = ~val + 1;

mask = ~0 << bits;
too_wide = val & mask;
return !too_wide;

答案 1 :(得分:1)

测试一个数字是否可以用N位2s补码数表示:简单地测试一下

  • 对于设置了低(N-1)位的单词的补充,按位和数字等于零
  • OR数字的高InputBitWidth-(N-1)位为1。
  

mask=(1<<(bits-1))-1; return ( !(val&mask) | !((val&~mask)^~mask) );