左移右移运算需要注意的地方

1、关于右移和左移需要注意的地方:

由于类型数值有位数限制,例如java中long型限制8个字节,总共8*8=64位,int型限制4个字节,总共4*8=32位,long和int都有一位是符号位,Java不允许一次性移位左操作数的所有位,对于int型来说也就是右操作数不能大于等于32。右操作数的低5位,5位二进制所代表的最大值为2^5-1,为31,所以取右操作数的低5位,就是只看右操作数的二进制的低5位,相当于右操作数对32取模的结果!相同的道理,long型就是右操作数的低6位有效。

示例(右移):

int a = 1;

a>>=1;//这里1为右操作数,二进制表示为00000000 00000000 00000000 00000001,它的低5位为红色部分,对32取模为1(其实就是和00000000 00000000 00000000 00011111进行&操作)

int a = 1;

a>>=33;//这里1为右操作数,二进制表示为00000000 00000000 00000000 00100001,它的低5位为红色部分,对32取模为1(其实就是和00000000 00000000 00000000 00011111进行&操作)

所以a>>=1和a>>=33的结果是相等的,都为0。

上面是右移的示例,左移的示例也是如此,这里不再赘述,左移结果都为2。

long类型和int类型一样,只不过右操作数取低6位,也就是和

00000000 00000000 00000000 00111111进行&操作

最终的目的就是要保证一次性移动位数不能超过左操作数类型的总位数

 

2、为什么byte、char、short类型的数移位结果很多时候不如预期?

举一个例子,代码如下:

short i = 1;
i<<=10;
System.out.println(i);
i = 1;
i <<= 16;
System.out.println(i);

结果是

1024

0

按照java的规定byte、char、short移位运算先把类型转换成int型,再进行移位,且结果为int型。

也就是这里面会先将i转换成int类型,所以相应的逻辑应该符合1,这样的话两个结果应该是1024和65536,但为什么是1024和0呢?

这里需要注意,由于short类型是两个字节,所以在赋值给i的时候会进行截断,拿1024来说:

1的二进制为

00000000 00000000 00000000 00000001

左移10位后变成

00000000 00000000 01000000 00000000

转换成short

01000000 00000000

结果为1024

左移16位后变成

00000000 00000001 00000000 00000000

转换成short

00000000 00000000

结果为0

3、为什么0b11111111111111111111111111111111二进制表示的值是-1?

具体的代码如下:

int d = 0b11111111111111111111111111111111;//补码
System.out.println(d);

运行结果是-1

这种情况下,计算机会把二进制值作为补码,那么原码就为0b10000000000000000000000000000001,也就是-1

4、

long a = -1;
a >>>=61;
System.out.println(a);
        
a = -1;
a >>>=-3;
System.out.println(a);
        
a = -1;
a >>>=-67;
System.out.println(a);

这里值都为7

需要遵守的规则如下:

1、移动的位数为负数a和移动的位数为'该类型位数'+a效果相同

2、>>>属于无符号的移动,也就是说不管是负数还是正数,符号位用0来补充

3、移动位数超过该类型的最大位数,最终的移动位数对类型位数取模

关于第一个,a>>>=61,由于是无符号右移,所以最终为正数7

关于第二个,a>>>=-3,符合第1条,long型位数为64,向右移动-3就是64+(-3)=61,所以也为7

关于第三个,a>>>=-67,符合第3条,先取模对64取模,为-3,所以也为7

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
左移运算右移运算是 Java 中的运算符,用于对二进制数进行移操作。左移运算符 `<<` 将二进制数向左移动指定的数,右边用 0 填充,相当于在原数的末尾添加 0,例如: ``` int a = 12; // a 的二进制表示为 1100 int b = a << 2; // b 的二进制表示为 110000,十进制为 48 ``` 右移运算符 `>>` 将二进制数向右移动指定的数,左边用符号填充,即正数用 0 填充,负数用 1 填充。例如: ``` int a = -12; // a 的二进制表示为 11111111 11111111 11111111 11110100 int b = a >> 2; // b 的二进制表示为 11111111 11111111 11111111 11111101,十进制为 -3 ``` 在这段代码中,使用了运算符来获取颜色值的 RGB 分量,具体来说: - 左移运算 `<<` 将 color 中的二进制数向左移动指定的数(8、16、24),得到对应的 RGB 分量。 - 右移运算 `>>>` 将左移后的二进制数向右移动指定的数,右边用 0 填充,得到无符号的 RGB 分量。 例如,假设 color 的二进制表示为 `11001100 01111011 01010010 00111101`,那么通过左移右移运算,可以得到: - 左移 8 后的二进制表示为 `01111011 01010010 00111101 00000000`,即十进制的 2031744。 - 右移 24 后的二进制表示为 `00000000 00000000 00000000 11001100`,即十进制的 204。 - 左移 16 后的二进制表示为 `01010010 00111101 00000000 00000000`,即十进制的 1376256。 - 右移 24 后的二进制表示为 `00000000 00000000 00000000 11001100`,即十进制的 204。 - 左移 24 后的二进制表示为 `00111101 00000000 00000000 00000000`,即十进制的 6324224。 - 右移 24 后的二进制表示为 `00000000 00000000 00000000 11001100`,即十进制的 204。 这样就可以通过运算获取到 color 的 RGB 分量,并进行后续的灰度转化计算。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值