我正在阅读“编程挑战:编程竞赛培训手册”这本书并且正在实现一个问题,我不理解运算符的使用c>> 1和比较if(n& 1),有人可以帮我知道他们的意思吗?
这是示例代码
#include <stdio.h>
#define MAX_N 300
#define MAX_D 150
long cache[MAX_N/2][2];
void make_cache(int n,int d,int mode)
{
long tmp[MAX_D];
int i,count;
for(i=0;i<MAX_D;i++) tmp[i]=0;
tmp[0]=1;count=0;
while(count<=n)
{
count++;
for(i=(count&1);i<=d;i+=2)
{
if(i)
tmp[i] = tmp[i-1] + tmp[i+1];
else if(!mode)
tmp[0]=tmp[1];
else
tmp[0]=0;
}
if((count&1)==(d&1))
cache[count>>1][mode]=tmp[d];
}
}
int main()
{
int n,d,i;
long sum;
while(1)
{
scanf("%d %d",&n,&d);
if(n&1)
sum=0;
else if(d==1)
sum=1;
else if(n<(d<<1))
sum=0;
else if(n==(d<<1))
sum=1;
else
{
make_cache(n,d,0);
make_cache(n,d,1);
sum=0;
for(i=0;i<=(n>>1);i++)
sum+=cache[i][0]*cache[(n>>1)-i][1];
}
printf("%ld\n",sum);
}
return 0;
}
答案 0 :(得分:15)
&GT;&GT;将位移位到右n位。所以这个:
1011 0101
向下移动1变为:
0101 1010
&amp;运算符按位进行,所以再次执行:
1011 0101
&安培;你得到1(并且意味着两者都必须是1,否则它是0):
1011 0101
&0000 0001
----------
0000 0001
希望这有助于回答您的问题!
答案 1 :(得分:7)
c >> 1
将其除以2(作为整数),n & 0x1
通常用于测试数字是否为奇数。
这里有一些文章:
http://irc.essex.ac.uk/www.iota-six.co.uk/c/e5_bitwise_shift_operators.asp
http://irc.essex.ac.uk/www.iota-six.co.uk/c/e4_bitwise_operators_and_or_xor.asp
答案 2 :(得分:2)
c&gt;&gt; 1表示将变量c右移1位,实际上与将其除以2相同。'&amp;'是一个按位AND运算符,用于测试是否设置了特定位。当你做n&amp; 1它与n&amp; 0x0001,检查变量的最低有效位是否置位。如果设置为false,则结果为true。
答案 3 :(得分:2)
c>>1
将C中的位移位到“右”,最后与无符号或正整数的整数除2相同。即5/2 = 2 == 0101>> 1 = 0010。
n&1
在n
和1. if (n&1)
之间执行二进制AND检查数字是否为奇数,因为奇数将使LSB为1而偶数则不会。
这样的“技巧”很可爱,一般来说价值不大(因为编译器应该做这些技巧)。在编程竞赛中,它是无用的,其中最重要的目标是产生正确的解决方案:这样的“技巧”只会妨碍易于阅读的源代码,从而使调试更加困难。
答案 4 :(得分:1)
那些是按位运算符。 &LT;&LT;和&gt;&gt;左右移位。 '&amp;' AND运算符是单个&符号。当你和两位时,如果两个位都是1,则结果为1;如果两个位中的任何一个为0,则结果为0.考虑它的一个好方法是必须将这两个位“设置”为等于1。
我写了一篇关于各种Bit Twiddling的教程。
答案 5 :(得分:1)
这些运算符用于比较奇数和偶数。
任何奇数的最低位是一直(即) 010(1)
默认情况下,如果(Oddnumber&amp; 1)= 1且(偶数&amp; 1 = 0)。
答案 6 :(得分:0)
如其他答案所述,这些是按位运算符。他们可能不熟悉,因为他们非常“接近硬件”操作。它们与计算机存储数字(二进制)的特定方式联系在一起,这就是为什么它们不是在标准数学类中教授的原因。他们接触程序员的原因是他们在硬件上非常快速,所以一些算法可以通过它们的使用得到显着优化。
答案 7 :(得分:0)
请注意&gt;&gt;无符号类型(无论是char,short,long还是long long)的行为与签名类型的行为不同。在这两种情况下,它都是右移,但对于无符号类型,左边的“新”位都是0,而对于有符号类型,它们是0或1,具体取决于原始的高位值。所以签名的角色:
1011 0101
向下移1成为
1101 1010
这使得它作为2次幂分割操作一致; -75 / 2 = -37.5,向下舍入到-38。