C 按位语句的澄清
如果(a&(a-1)/2)在C中是什么意思C 按位语句的澄清,c,bitwise-operators,C,Bitwise Operators,如果(a&(a-1)/2)在C中是什么意思 #include <stdio.h> int main() { int a; scanf("%d", &a); if(a & (a-1)/2) { printf("Yes\n"); } else{ printf("No\n"); } return 0; } #包括 int main() { INTA; scanf(“%d”和“&a”); 如果(a
#include <stdio.h>
int main()
{
int a;
scanf("%d", &a);
if(a & (a-1)/2)
{
printf("Yes\n");
}
else{
printf("No\n");
}
return 0;
}
#包括
int main()
{
INTA;
scanf(“%d”和“&a”);
如果(a&(a-1)/2)
{
printf(“是\n”);
}
否则{
printf(“否”);
}
返回0;
}
我不明白这里的/操作员的意思。除法运算符在条件中是什么意思?除法运算符
/
只是将左手边除以右手边。在这种情况下,右边是2,因此它将a-1
右移一位(算术移位,符号扩展整数)
因此,对于a>=0
,整个表达式计算a
和((a-1)>>1)
是否设置了任何相同的位(在这种情况下和将产生非零值)。对于a=0
,则(a-1)/2
==a/2
(因为四舍五入总是接近零)。因此,这相当于(对于a>=0
)到a&(a>>1)
,如果a
中任何位的右边的位被设置,即如果有两个或多个相邻的位,这将是一个
如果a除法运算符/
只是将左手侧除以右手侧。在这种情况下,右边是2,因此它将a-1
右移一位(算术移位,符号扩展整数)
因此,对于a>=0
,整个表达式计算a
和((a-1)>>1)
是否设置了任何相同的位(在这种情况下和将产生非零值)。对于a=0
,则(a-1)/2
==a/2
(因为四舍五入总是接近零)。因此,这相当于(对于a>=0
)到a&(a>>1)
,如果a
中任何位的右边的位被设置,即如果有两个或多个相邻的位,这将是一个
如果a它从a中减去1,然后将其除以2,然后进行位与运算。它从a中减去1,然后将其除以2,然后进行位与运算。在表达式a&(a-1)/2中有位与运算符和除法运算符。这是非常不寻常的,这些是一起使用。因此,我不知道优先级是什么(它是将a-1除以2,然后用a进行按位and运算,还是对a和a-1进行按位and运算,然后将结果除以2)。实际上,我并不关心优先级是什么,因为我不知道编写代码的程序员假定它是什么优先级
如果你看到这样的代码,你需要找出它的作用,你需要找出它的意图是什么,如果两者都是相同的,你需要添加括号来明确意图,如果它们不一样,你已经发现了一个bug,并找出它如何影响程序以及如何处理它 在表达式a&(a-1)/2中有一个按位and运算符和一个除法运算符。这是非常不寻常的,这些是一起使用。因此,我不知道优先级是什么(它是将a-1除以2,然后用a进行按位and运算,还是对a和a-1进行按位and运算,然后将结果除以2)。实际上,我并不关心优先级是什么,因为我不知道编写代码的程序员假定它是什么优先级
如果你看到这样的代码,你需要找出它的作用,你需要找出它的意图是什么,如果两者都是相同的,你需要添加括号来明确意图,如果它们不一样,你已经发现了一个bug,并找出它如何影响程序以及如何处理它 对于非负值,除以2相当于将其向右移动1位。对于负值,它是不等价的,但我怀疑代码的作者并不打算使用负值
(注意,这种非等价与异类非二进制补码结构或算术筛选无关,在C和C++语言中,需要对0个循环进行符号划分,这使得在2个补码结构上通过简单移位来实现符号化除法是不可能的。需要后移校正。
现在,至于整个a&(a-1)/2
表达式在做什么……让我们只考虑非负值
减去1相当于将数字中的所有尾随0位倒置,然后将最后一个(最低有效)1位倒置。除以2相当于右移1位
在&
操作的上下文中,整个操作相当于:杀死a
中的最后1位,将整个操作向右移动1位,并使用原始值对其执行&
操作
我看不出在这种情况下杀掉最后1位有什么意义。看起来对于正值,整个事情相当于a&(a/2)
(即对于a&(a>>1))
),对于非负值,它只检测原始a
中是否有两个相邻的1位,除以2相当于将其向右移动1位。对于负值,它是不等价的,但我怀疑代码的作者并不打算使用负值
(注意,这种非等价与异类非二进制补码结构或算术筛选无关,在C和C++语言中,需要对0个循环进行符号划分,这使得在2个补码结构上通过简单移位来实现符号化除法是不可能的。需要后移校正。
现在,至于整个a&(a-1)/2
表达式在做什么……让我们只考虑非负值
减去1相当于将数字中的所有尾随0位反转,然后将最后一个(最低有效)1位反转。除以2等于
#include <stdio.h>
#include <stdlib.h>
int
main (int argc, char **argv)
{
int i;
for (i = 0; i < 256; i++)
{
printf ("%3d %s\n", i, (i & (i - 1) / 2) ? "yes" : "no");
}
exit (0);
}
0 no
1 no
2 no
3 yes
4 no
5 no
6 yes
7 yes
8 no
9 no
10 no
11 yes
12 yes
13 yes
14 yes
15 yes
16 no
17 no
18 no
19 yes
20 no
21 no
22 yes
23 yes
24 yes
25 yes
26 yes
27 yes
28 yes
29 yes
30 yes
31 yes
32 no
33 no
34 no
... abbreviated for clarity ...