总结:在java中,对byte和short类型的 右移操作 必须先进行 & 0xff 后再右移,避免byte或short是负数的情况下,导致 右移操作前 自动升为int,前面补了很多1,此时右移会把1冲到高位上,从而错误;
int 和 long没有任何问题;
左移没有这个问题,因为左移及时自动转换成int 在前面补了很多1后,后面的截断 还是会把左边的都截掉,就是说 左移 永远是从右边补0,而右移由于自动转换成int的存在,会导致即使使用了>>>的情况下
左边还是会补1,因为负数转换成int的时候,前面的每一位都是1了。留意。
((bytes[0] & 0xff) >>> 3);
1.举例:
public static void main(String[] args) { byte[] bytes = new byte[1]; bytes[0] = 31;//00011111 bytes[0] <<= 3;//11111000 bytes[0] >>>= 3;// 这步很诡异的变成了 11111111 ???? System.out.println(bytes[0]);// -1;最终的结果为-1??? }
接下来调试看下:
导致输出的结果为-1,而不是31的原因是,在java中 对byte和 short进行位操作的话,会先默认自动转换为int 再进行位操作;
public static void main(String[] args) { byte[] bytes = new byte[1]; bytes[0] = 31;//00011111 /* bytes[0] <<= 3;这步发生的情况如下: 0000 0000 0000 0000 0000 0000 0001 1111(先把byte[0]转换成int) 0000 0000 0000 0000 0000 0000 1111 1000(再左移3位) 1111 1000(再赋值给byte[0],截断) */ bytes[0] <<= 3; /* bytes[0] >>>= 3; 又发生了什么: 1111 1111 1111 1111 1111 1111 1111 1000(把当前的byte[0]转换成int,由于是负数,所以转换成了这样,左边按符号位全部补1,就是由这步自动转换导致了问题,解决方法就是把这步自动转换前面的1去除,用 & 0xff) 0001 1111 1111 1111 1111 1111 1111 1111(右移3位) 1111 1111(赋值截断,最终 byte[0]的值,可见变成全是1了) */ bytes[0] >>>= 3; /* 输出byte[0]发生了什么,输出byte[0]就是把byte[0]的值转换成10进制,计算机发现byte[0]的最高位是1,说明是负数, 计算机认为它是负数后,负数在计算机中是以补码的方式来存储的,所以具体的10进制的值是它的原码,需要把补码转换成原码 规则:1.补码符号位不变,其余位取反; 2.取反后加1,就是原码 1000 0000(符号位不变,其余位取反) 1000 0001(取反后加1,就是原码) 原码就是具体的值,可见是-1 */ System.out.println(bytes[0]); }
解决方法,系统自动把byte[0]由byte自动向int 转换后的值再与0xff取与运算,使其一个字节的前面的位全部为0:
1111 1000 --> 1111 1111 1111 1111 1111 1111 1111 1000(自动向int转换)
然后我们再通过& 0xff 让它们取与运算:
1111 1111 1111 1111 1111 1111 1111 1000
0000 0000 0000 0000 0000 0000 1111 1111
=
0000 0000 0000 0000 0000 0000 1111 1000(这个才是我们想要的)
与&0xff 运算后,再说右移的事,就解决了这个问题;
总结:在java中,操作byte右移前一定要先 &0xff 做与运算,才能右移;
public static void main(String[] args) { byte[] bytes = new byte[1]; bytes[0] = 31;//00011111 bytes[0] <<= 3; bytes[0] = (byte) ((bytes[0] & 0xff) >>> 3); System.out.println(bytes[0]); }
==================================================================================================================
接下来看下short:
看下 int :
看下long:
本文来自博客园,作者:del88,转载请注明原文链接:https://www.cnblogs.com/del88/p/15839209.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
2020-01-24 Spring Boot 跨域的问题