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

Finding if a value falls within a range, using bitwise operators in C

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

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

我需要确定给定的 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 <= val <=maxInRange。我希望我可以使用大于或小于运算符,但我们不允许。检查这个的按位方法是什么?

感谢您的帮助!

二进制补码负数的高位始终为“1”。

您可以通过从 FF -> 00 -> 01 将负数转换为正数(反之亦然)。也就是说,反转位,加 1。(01 -> FE -> FF 也可以:反转位,加 1)

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

我不确定您的约束是否允许您使用数组。它们会加快某些事情的速度,但可以用循环或 if 语句代替。

无论如何,如果在您的输入中设置了 1 << (NUM_INT_BITS-1),那么它就是负数。 反转,加一。

现在,考虑0。零是一个常数,无论有多少位,它总是相同的。但是如果你将 0 取反,你会得到 "all the bits",它会因架构而改变。所以,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 应该是什么?嗯,是 "all set bits except the bottom however-many"。您可以通过从 "all set bits" 开始并将它们向上移动(又名 "left") however-many 地方来构造它:

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;

要测试一个数字是否可以用 N-bit 2s 恭维数字表示:只需测试

  • 数字 bitwise-and 与低 (N-1) 位设置的单词的补语等于零
  • OR 数的高InputBitWidth-(N-1)位为1

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