关于对2取模的误区

    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”这个条件相当于没有加,意思是有没有这个都无所谓,结果都会是正确的。
    由此建议读者,在这种运算符不明白的情况下,尽量加上括号,以免出现不必要的错误。谢谢大家听我唠叨这么久。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值