C++(x&-x)的含义

C++语言中有一个比较常用的语句:

x&-x

 这个语句有些人可能不知道,接下来我们就来解释一下它的含义

1.-x的含义

-x其实就是将x按位取反之后加1,这里提到的取反在C++中是一个"~",其含义是:

在二进制下的1变为0,0变为1

我们可以在C++上试一下:

//这是代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int x=1;
    cout<<~x;
    return 0;
}

输出:

//这是输出
-2

这是为什么呢???

因为数字1的二进制编码是:

0000 0000 0000 0001

二进制的最高位表示符号位,符号位是1表示是负数,0表示是正数

所以说取反后的值是:

1111 1111 1111 1110

所以说~1对应的十进制结果是:

-32766

这也不对呀,为什么呢???

其实是因为我们的二进制负数在C++中是以补码的形式存放的,真正的结果应该将其转化为源码再转化为十进制,负数的补码等于源码除符号位外按位取反再加1,因此1111 1111 1111 1110-1是:1111 1111 1111 1101,再将其除符号位之外按位取反就是:1000 0000 0000 0010,再转化为十进制:-2我们现在就已经成功的算出来了,而我们的-x其实就是~x+1,所以最后在+1,结果是-1,其实-x的结果就是在x前加上一个"-",最后我们在C++上试一试:

//这是代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int a=1;
	cout<<(-a);
	return 0;
}

输出:

//这是输出
-1

没错,跟我们算出来的完全一致。

2.x&-x的含义

首先我们要先理解一下符号"&","&"叫做按位与,也叫二进制中的乘法,比如1&1=1,1&0=0,0&1=0,0&0=0,如果两位都为1,则结果为1,否则为0,我们再在C++上试一试:

//这是代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int a=5;
	int b=2;
	cout<<(a&b);
	return 0;
}

 输出:

//这是输出
0

这是又是为什么呢???

因为我们2的2进制是:

0000 0000 0000 0010

而5的二进制是:

0000 0000 0000 0101

像刚才说的,两位都为1结果才是1,不然为0:

       0000 0000 0000 0010

&     0000 0000 0000 0101

---------------------------------------

        0000 0000 0000 0000

转化为十进制是0。

那么我们再来看看x&-x,首先是代码:

//这是代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int a=5;
	cout<<(a&-a);
	return 0;
}

输出:

//这是输出
1

然后让我们来模拟一下,5的二进制是:0000 0000 0000 0101,而-5的二进制是:

1000 0000 0000 0101,5&-5的值是:

       0000 0000 0000 0101

&     1000 0000 0000 0101

---------------------------------------

        0000 0000 0000 0101

所以答案是6!!!

额……又双叒错了!!!

因为负数在C++中是以补码存储的,-5的补码是:1111 1111 1111 1011,结果应当是:

0000 0000 0000 0001,转换为十进制是1,现在计算的答案正确了,那么我们"x&-x"的作用又是什么呢???我们"x&-x"的作用是在二进制下x从右往左数第一个非0的位对应的值,比如5的二进制是0000 0000 0000 0101,从右往左数第一个非0的位是第0位,也就是最低位,二进制中第几位对应的值就是二的几次方,比如第0位就是2的0次方=1,第1位就是二的1次方=2,而5的二进制中从右往左是第一个非0的位是第0位,2的0次方=1,所以答案是1,从左往右数第一个非0的位也叫"lowbit"位,说到"lowbit"位,有兴趣的还可以继续看下面的拓展:x&x-1的含义。

3.拓展:x&x-1

x&x-1和x&-x都跟"lowbit"有关,x&x-1的作用是清除x的"lowbit"位,比如5的二进制是:

0000 0000 0000 0101,它的"lowbit"位是第0位,清除之后是:0000 0000 0000 0100,转换为十进制是:4,接下来我们在C++上试一试:

//这是代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int a=5;
	cout<<(a&a-1);
	return 0;
}

输出:

//这是输出
4

跟我们算出来的一样。

4.备注

我这次使用的软件是Dev-C++ 5.11,使用的编译器是GNU C++11,另外还要提醒大家,&、~ 等都是位运算符号,写的时候一定要加上括号,否则会编译错误(CE)!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值