如何在C中仅使用按位运算符来检查值是否大于7?

问题描述 投票:0回答:3

对于这道题,如果参数大于 7,则要求返回 1,否则返回 0。

例如,如果 x 为 8,则函数将返回 1。如果 x 为 7,则函数将返回 0。

唯一允许的合法运算符是 (! ~ & ^ | + << >>),它禁止使用其他任何运算符,例如 -、for 循环、while 循环、if 语句等。

我们可以假设系统使用 2 的补码和整数的 32 位表示,以算术方式执行右移,并且当将整数移位超过字大小时会出现不可预测的行为。

我知道不使用 - 运算的减法可以用 ~ 来完成,但说实话,我不知道如何从逻辑上思考这个问题。

c bit-manipulation bitwise-operators twos-complement
3个回答
6
投票

在二进制中,十进制数

7
111
。因此,大于 7 的数字将始终具有比 7 的二进制表示中的最高有效位(即从 0 编号时的位 3)组更高的有效位组。因此,如果您只处理无符号数字,那么这个测试就足够了:

int bitwise_is_n_gt_7 (unsigned int value)
{
    return value & 0xFFFFFFF8; // assuming size 32-bits adjust as  necessary
} 

如果您正在处理带符号的数字,您还必须处理数字为负数的可能性,因此您需要测试:

int bitwise_is_n_gt_7 (int value)
{
    return (!!(value & 0x7FFFFFF8) & !(value & 0x80000000));
}

2
投票

>7 与 ≥8 相同。

您可以使用整数除法检查一个正数是否≥另一个正数。如果结果非零则更大。

除法不是“位运算”,但 8 是 2 的幂,并且有一个“位运算”被定义为除以 2 的幂:

>>

所以我们可以使用:

n >> 3

将正整数右移三位会删除三个最低有效位,同时移动其他位。但我们不在乎其他人是否感动。

所以我们也可以使用:

n & ~7

1
投票

如果无符号数为

7
或更小,则唯一要设置的位将是表示
4
2
1
的位。
下一个较高位表示
8
,大于 7。

因此,如果您通过屏蔽“关闭”最低 3 位(代表

4
2
1
),并检查是否还有任何位仍然保留,则原始数字为 8 或更大.

if (number & ~0b0111) // Turn OFF the lowest 3 bits, keep all the others.
{
    printf("Number is 8 or Greater\n");
}
else 
{
    printf("Number is 7 or less\n");
}

使用

0b
前缀是非标准的(但在许多编译器中很常见),因此您可以选择将
0b0111
替换为
0x07
,或者只是普通的
7
来代替:

if (number & ~7)  { /* number is greater than 7 */ }

示例代码:

#include <stdio.h>

int main(void) {
    for(int i=0; i<30; ++i)
    {
        printf("%d is %s 7\n", i, i&~7? "greater than" :"less than (or equal to)");
    }
    return 0;
}

输出

0 is less than (or equal to) 7
1 is less than (or equal to) 7
2 is less than (or equal to) 7
3 is less than (or equal to) 7
4 is less than (or equal to) 7
5 is less than (or equal to) 7
6 is less than (or equal to) 7
7 is less than (or equal to) 7
8 is greater than 7
9 is greater than 7
10 is greater than 7

从这个基本概念开始,要处理负数,您需要检查“符号位”是否已设置。如果设置了,数字自动为负数,并且自动小于7。

将其全部分解:

#include <stdio.h>
#include <stdbool.h>

int main(void) {
    for(int i=-10; i<+10; ++i)
    {
        bool is_negative_bit_off = !(i>>31);
        bool is_bit_8_or_higher_set = !!(i&~7);

        if (is_negative_bit_off && is_bit_8_or_higher_set)
        {
            printf("%d is greater than 7\n", i);
        }
    }
    return 0;
}

然后简化它:

int main(void) {
    for(int i=-10; i<+10; ++i)
    {
        bool num_greater_than_7 = !(i>>31) & !!(i&~7);

        if (num_greater_than_7)
        {
            printf("%d is greater than 7\n", i);
        }
    }
    return 0;
}

所以你的问题的最终表达/答案是:

bool num_greater_than_7 = !(i>>31) & !!(i&~7);

(读作“该数是正数吗?该数是否大于 7?”)

使用的运算符为

!
>>
&
~

© www.soinside.com 2019 - 2024. All rights reserved.