关于“<<“、“>>“和“>>>“的个人理解(探索ing)
首先,我发表此文章是因网上大部分对于该三个位运算符,在我看来讲的不是很通俗(当时我是懵逼的,理解后茅塞顿开),所以我整整了我的版本。(仅代表个人看法)
关于原码、反码、补码(重点,后面会用到的!)
正数---->原码=反码=补码
负数---->原码->反码(所有位取反)->补码(反码+1)
快速导航 (ps:网页右上角也有目录)
首先是"<<"
"<<"该符号用于二进制数(转换为补码)所有位数进行左移,左移几次,就末尾加几个0。(通俗的说)
正数例子
int x = 16; 其二进制数为10000
int y = 2;
int z = x << y; x左移y次
z结果为64 (64的二进制为1000000)
如上,是左移了两次,所以在末尾加两个0。
为了方便理解,如下再加几个例子。
8 << 2的结果为32 1 << 2的结果为4 3 << 2的结果为12
8 << 3的结果为64 1 << 3的结果为8 3 << 3的结果为24
负数例子----情况和正数有大区别
int x = -8,其二进制为1000
int y = 2
int z = x << y
z的结果为-32
运算过程:
先转为补码:1000 (原码)—>0111 (反码)—>1000 (补码),然后再进行左移,左移两次为100000(补码)
然后再将补码转为原码:100000 (补码)->011111 (反码)->100000 (原码),100000的十进制数为32,但是因其是负数所以结果为-32。(未用机器码表示)
插一句话->机器码表示是,正数最前面加0,负数最前面加1。即上述-8的机器码是11000,16的机器码则是01000
同上举例如下
-3 << 1的结果为-6 -3 << 2的结果为-12 -3 << 2的结果为-24
-4 << 1的结果为-16 -4 << 2的结果为-32 -4 << 3的结果为-64
-6 << 1的结果为-12 -6 << 2的结果为-24 -6 << 3的结果为-48
ps:(拖了很多天才开始完成下面内容的,哈哈QWQ)
这边是">>":
">>“君和”<<“有些类似,区别在于前者是末尾发生改变,而后者是前面发生改变。这样说可能有些懵逼,下面开始讲解(能理解这个,理解后面的”>>>"就不难了)
">>"该符号通俗的说是二进制数所有位数(补码)进行右移,右移几位,就在最前面补0或1(值是正数,补0。值是负数,则补1),然后取原码值。
下面开始进入正题
正数君率先出列
int x = 10; 其的二进制为1010
int y = 2;
int z = x >> y;
z的值为2,其的二进制数为0010 (补码)
运算过程:1010 (原码)—>1010 (反码)—>1010 (补码),补码右移两位后为0010 (因正数的补码就是原码,所以转为十进制就是2了)
举例如下:
8 >> 2的结果为2 16 >> 2的结果为4 64>>2的结果为16
9 >> 2的结果为3 13 >> 2的结果为3 35 >> 2的结果为8
负数君骂骂咧咧的来了
int x = -10; 其的二进制为1010
int y = 2;
int z = x >> y;
z的结果为-3其的二进制为0011 (原码)
运算过程:
1010 (原码)—>0101 (反码)—>0110 (补码),右移两位则为1101 (补码),
将其变回原码:1101 (补码)—>1100 (反码)—>0011 (原码),该值十进制就是3啦。
举例如下:
-8 >> 2的结果为-2 -16 >> 2的结果为-4 -64 > >2的结果为-16
-9 >> 2的结果为-3 -13 >> 2的结果为-4 -35 >> 2的结果为-9
最后是">>>":
关于">>>",如能理解前者内容(">>"),理解这个应该不难。
这个">>>“符号的运算称为“无符号右移”,无符号指的是最高位那个数,不管正或负数右移,都是加补0,因此就相当于无符号了。
就是上面这个图所述的(前面提到过QWQ)
然后这个符号的运算嘛,基于32位数运算。其实,其跟”>>“符号类似,也是往右移,前者是补码有符号右移x位(最高位始终如初),后者是补码无符号右位移x位(最高位会发生改变),且前者是取原码值,后者是取补码值。
下面开始
首先是正数君
int x = 10; 其变为32位为: 00000000000000000000000000001010 (32位没毛病的)
int y = 2;
int z = x >>> y;
z的结果为2(其变为32位为: 00000000000000000000000000000010 ) ps:正数的补码等于原码
我相信能理解前面的”>>“和”<<"就不难理解这个了,栗子也整几个吧。
一些栗子如下
8 >>> 2的结果为2 16 >>> 2的结果为4
8 >>> 3的结果为1 16 >>> 3的结果为2
Ok,下面是负数君了,也不难的
int x= -10; 其的32位是: 10000000000000000000000000001010 (原码)
int y = 2;
int z = x >>> y;
z的结果是1073741821 其的32位是: 00111111111111111111111111111101 (补码)
运算过程:
10000000000000000000000000001010 (原码)—>111111111111111111111111111110101 (反码)—>11111111111111111111111111110110 (补码),补码右移两位后为00111111111111111111111111111101 (这个就是结果值了啦)
ps:为了方便更深刻理解建议手写一下,笔者就是。(不容易啊,哈哈)
栗子又来了,快接好啊!!!
-8 >>> 2的结果为1073741822 -16 >>> 2的结果为1073741820
-8 >>> 3的结果为536870911 -16 >>> 3的结果为536870910
OK,就是这样,不难对吧,如果还无法理解或有所不足,请评论区评论或私信给我。(俺有时间的回复,放心!)
重中之重的是,感谢你的阅读,感恩