您的位置:首页 > 其它

关于对2取模的误区

2015-06-27 12:14 411 查看
2015年6月27日。

先来看个知识点,有一个数N,设MOD = N & 1,则MOD就是N % 2的结果。&就是按位与的意思,来举个生动的例子。

N = 3,N转换成2进制就是11,将这个11与1按位与,将1高位不足补0,则11与01按位与,结果MOD = 1,这个MOD就是3 % 2的结果。这里N是个奇数,当N为偶数此处就不再举例。

这个N & 1有什么用呢,显然它可以直接得到一个数模2的结果,通过这个结果我们能够判断是奇数还是偶数。如果N & 1等于1,说明N是奇数,否则N是偶数。

本文的题目叫做“关于对2取模的误区”,那我们就言归正传。看代码:

int a = 11, b = 12;
    if(a & 1 == 1) a = 1;
    if(b & 1 == 0) b = 1;
    printf("%d %d\n", a, b);
读者朋友猜一猜a、b的值,a = 1? 11,b = 1, b = 12?按照上文所诉a & 1的结果肯定是1,if(a & 1 == 1)这个条件肯定是真,所以a = 1。再看看b的值b & 1的结果肯等是0,if(b & 1 == 0)这个条件肯定也是真,那么b的值也自然等于1,好了我们去调试这个程序,发现a = 1, b = 12。额,这个结果怎么跟我们分析的结果是不一样的,是什么问题呢?难道是一个数N & 1 不是取得模2的结果。其实不然,这个结论肯定是正确的,那么问题到底出在哪里呢?通过加括号也许我们能明白一点什么,看下面:



int a = 11, b = 12;
    if(a & 1 == 1) a = 1;
    if((b & 1) == 0) b = 1;
    printf("%d %d\n", a, b);


我们在(b & 1)这里加了一个括号,然后调试程序结果跟我们分析就一致了,a = 1, b = 1。按道理说这里加括号与否都是一样的,其实这里就有个很大的问题,查阅相关资料才明白,==运算符的优先级高于&运算符,第一次的代码,if(b & 1 == 0),计算机先处理1 == 0这一部分结果是0,然后再处理b == 0这一部分,所以这个为0即假,自然b仍然等于12。

第二份代码if((b & 1) == 0)这个加了括号之后,计算机就先处理b & 1,这结果是0,然后在处理0 == 0,显然为真,所以b就会为1。b的问题解决了。那么a为什么是正确的,上文已说过==运算符优先级是高于&运算符,if(a & 1 == 1),计算机先处理1 == 1,这个结果仍为1,然后再处理a & 1,这个结果肯定是1即真,所以a会被赋值为1,这个a的例子说明了什么,意思就是“== 1”这个条件相当于没有加,意思是有没有这个都无所谓,结果都会是正确的。

由此建议读者,在这种运算符不明白的情况下,尽量加上括号,以免出现不必要的错误。谢谢大家听我唠叨这么久。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: