使用 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) );
所以我正在研究这种方法,但仅限于使用这些运算符:
<<, >>, !, ~, &, ^, |, +
我需要确定给定的 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) );