在Java中,对 byte 和 short 类型 进行位操作的时候,严重留意事项
总结:在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:

在Java中,对 byte 和 short 类型 进行位操作的时候,严重留意事项的更多相关文章
- 详解java中的byte类型
Java也提供了一个byte数据类型,并且是基本类型.java byte是做为最小的数字来处理的,因此它的值域被定义为-128~127,也就是signed byte.下面这篇文章主要给大家介绍了关于j ...
- 深入理解java中的byte类型
作者 | 进击的石头--GO! 来源 | https://www.cnblogs.com/zl181015/p/9435035.html#4432849 Java也提供了一个byte数据类型,并且是基 ...
- java中如何理解:其他类型 + string 与 自增类型转换和赋值类型转换
java中如何理解:其他类型 + string 与 自增类型转换和赋值类型转换 一.字符串与其他类型连接 public class DemoString{ public static void mai ...
- java中读取特殊文件的类型
java中读取特殊文件的类型: 第一种方法(字符拼接读取): public static String getType(String s){ String s1=s.substring(s.index ...
- java中的byte
8 bit (位) = 1 Byte (字节) java中的byte就是Byte 1024 Byte = 1KB 1024 KB = 1MB 1:“字节”是byte,“位”是bit : 2: 1 by ...
- Java中的基本类型和包装类型区别
首先看一下几个测试题,验证一下java中对基本类型和包装类型的理解,看看最后输出的答案对不对,答案在这篇博客中哦: // 第一题: 基本类型和包装类型 int a = 100; Integer b = ...
- Java中的两种异常类型及其区别?
Java中的两种异常类型是什么?他们有什么区别? Throwable包含了错误(Error)和异常(Excetion两类) Exception又包含了运行时异常(RuntimeException, 又 ...
- JAVA中如何获取变量的类型
JAVA中如何获取变量的类型? package xiya; public class Demo { public static void main(String[] args) { String ty ...
- java 彻底理解 byte char short int float long double
遇到过很多关于 数值类型范围的问题了,在这做一个总结,我们可以从多方面理解不同数值类型的所能表示的数值范围 在这里我们只谈论 java中的数值类型 首先说byte: 这段是摘自jdk中 Byte.ja ...
- (转) Java中的负数及基本类型的转型详解
(转) https://my.oschina.net/joymufeng/blog/139952 面这行代码的输出是什么? 下面两行代码的输出相同吗? 请尝试在Eclipse中运行上面的两个代码片段, ...
随机推荐
- C# ,使用“^”运算符对数字加密
原理:"异或"运算符"^", 用于比较两个二进制数的响应位.计算过程如果两个二进制数的相应位都为1或两个二进制数的相应位都为0,则返回0:如果两个二进制数的相应 ...
- WPF|黑暗模式的钱包支付仪表盘界面设计
阅读目录 效果展示 准备 简单说明 + 源码 结尾(视频及源码仓库) 1. 效果展示 欣赏效果: 2. 准备 创建一个WPF工程,比如站长使用 .NET 7 创建名为 WalletPayment 的W ...
- 同步FIFO设计
FIFO有一个读口和一个写口,读写时钟一致是同步FIFO,时钟不一致就是异步FIFO IP设计中通常使用的是同步FIFO 异步FIFO通常使用在跨时钟域设计中 RAM(Random Access Me ...
- 2023年度总结,互联网寒冬是躺平OR寻找风口
一.前言 又到了年底,这一年过的真的好快,犹如白驹过隙. 身体快跃过去了,灵魂还没有. 拿起键盘却迟迟无法下手,经过三天终于完成了! 这是很颓很丧的一年,很难看到自己的成长,就像登山卡在半山腰,开车堵 ...
- Kafka的部分初始化参数的学习与整理
Kafka的部分初始化参数的学习与整理 背景 前段时间跟同事一起处理过kafka的topic offset的retention 时间与 log 的retention时间不一致. 导致消息还有, 但是o ...
- [转帖]xtrabackup2.4备份恢复脚本
https://developer.aliyun.com/article/534230#:~:text=xtrabackup2.4%E5%A4%87%E4%BB%BD%E6%81%A2%E5%A4%8 ...
- [转帖]金仓数据库KingbaseES V8R6 中unlogged表
KingbaseESV8R6有一种表称为unlogged,在该表新建的索引也属于unlogged.和普通表的区别是,对该表进行DML操作时候不将该表的变更记录变更写入到wal文件中.在数据库异常关机或 ...
- [转帖]华为毕昇 JDK 8u292、11.0.11 发布!
https://baijiahao.baidu.com/s?id=1705499834793298544&wfr=spider&for=pc 2021 年 6 月 30 日,毕昇 JD ...
- element-ui中Select 选择器列表内容居中
<el-select class="my-el-select" v-model="tenantCont" placeholder="请输入机构标 ...
- 【JS 逆向百例】网洛者反爬练习平台第四题:JSFuck 加密
关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后 ...