Java对byte 的 + - * / >> >>> << & | ^ (加,减,乘,除,右移,左移,无符号右移,位与,位或,位异或)操作,均会是首先将byte转化为int, 再行运算。这一事实可能导致多种问题:
假设我们想进行如下byte运算: 1111 1000 右移1位,再与0000 0001 或运算,得 0111 1101。
直觉写程序如下:
byte b = 0xf8;
byte b2 = b >> 1 | 0x01;
这个写法里有多重错误,现逐个纠正:
1 编译器报错,int无法直接自动转化为byte
为解决此问题,加强制转化。
byte b = (byte)0xf8;
byte b2 = (byte)( (b >> 1) | 0x01);
2 输出为 1111 1101 不是我们想要的 0011 1101
原因是>> 是有符号右移,当符号位为1时,左侧补的是1而非0。
修改为使用 >>> 无符号右移:
byte b = (byte)0xf8;
byte b2 = (byte)( (b >>> 1) | 0x01);
3 运行后发现输出依然为 1111 1101
原因是byte在运算前先转化为int再行位运算,因此分解后的运算步骤如下:
b 转化为int 1111 1000 转化为 11111111 11111111 11111111 11111000
无符号右移1位 01111111 11111111 11111111 11111100
与 0x01 按位或 01111111 11111111 11111111 11111101
强制转化回byte 11111101
解决方案,在右移运算前先 位与 0xff
byte b = (byte)0xf8;
byte b2 = (byte)( ((b & 0xff )>>> 1) | 0x01); //注意必须加括号,因为 >>> 的优先级高于 &
4 运行后发现输出为我们想要的结果 0111 1101。运算步骤分解如下:
b 转化为int 1111 1000 转化为 11111111 11111111 11111111 11111000
和0xff 进行 & 操作 00000000 00000000 00000000 11111000
无符号右移1位 00000000 00000000 00000000 01111100
与 0x01 按位或 00000000 00000000 00000000 01111101
强制转化回byte 01111101
5 关于System.out.println();
byte b = (byte)0xf8;
System.out.println(b); --最终输出为-8
运算步骤为:
b 转化为int 1111 1000 转化为 11111111 11111111 11111111 11111000
取符号位 - -1111111 11111111 11111111 11111000
取返+1(因为是按补码运算) -0000000 00000000 00000000 00001000
输出 -8
最终结论:
1 区分使用 >> 和 >>>
2 在 >> 操作前要首先 & 0xff
3 注意符号优先级,正确使用括号。
4 需要强烈注意的一点是 & 的优先级小于 + . 因此 a = b & 0xff + 2000 的结果 可能不是你想要的
附:
打印byte,int 每个bit值的函数。
public static void printByte(byte b){
for(int i = 7; i >=0 ; i --){
int shiftleft = (b >> i) & 0x01;
System.out.print(shiftleft);
}
System.out.println();
}
public static void printInt(int b){
for(int i = 31; i >=0 ; i --){
int shiftleft = (b >> i) & 0x01;
System.out.print(shiftleft);
}
System.out.println();
}
分享到:
相关推荐
java基本类型转byte,设计原码、补码、反码、左右位移等知识,赚点积分
用于java,byte与各种对象的转换,Integer、short、hex、string
主要整理了Java中byte数组与其他基本类型的转换
java_byte与char、String互转.................
JAVA转byte[]为int,long,double
java基本类型与byte数组互相转换.pdf
网络资源的整合,以及自己摸索使用JavaScript进行byte计算的路,包括详细的文档,范例代码(java和js按算法crc16生成crc码),为下载其中资源,花费若干分,所以设定了下载分。谢谢大家!
使用链式编程写法实现Java中byte数组的拼接。例如byte[] bytes = ByteUtils.get().add(0x41).add(07).add(11).add("15288930000").add(0x45).toArray();更灵活用法请参考Mybytes
用于编译class类文件,能够完成class文件的读取、修改功能.exe
Java bytes数组与基本类型的相互转换 Int -> Bytes int64ToByte8 int48ToByte6 int40ToByte5 int32ToByte4 int24ToByte3 int16ToByte2 int8ToByte Bytes -> Int bytesToInt64 bytesToInt48 bytesToInt40 bytesTo...
java写的byte转float值IEEE标准
ip地址转4字节byte,char转2字节byte,byte数组转char,int整数转换为4字节的byte数组,byte数组转换为int整数,double类型转8字节数组,8位数组转double,long整数转换为8字节的byte数组,short整数转换为2字节的...
java基本类型与byte数组互相转换
[java]将Byte存入blob.rar
Java String与Byte类型转换;用到网络编程.
java byte:字节型
java 获得指定文件的byte数组 ,根据byte数组,生成文件。
做Java课程设计有用到的例子,是个看了就能上手的例子。
今天小编就为大家分享一篇java中两个byte数组实现合并的示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧