java字节、位移以及进制转换
数据存储方式
众所周知,java中的数据都是以二进制的形式存储在计算机中的,但是我们看到的数据怎么是10进制的,因为java提供了很多进制自动转换的方式。
位移
向左位移是*2的幂次,一般都是正数操作,右侧补0,所以不存在有符号左位移
向右位移会存在负数,所以存在有符号和无符号右移的问题,左侧补0.
public class Binary {
public static void main(String[] args) {
//转换成2进制,用Integer.toBinaryString()
//转换成16进制,用Integer.toHexString()
int i = 89;
System.out.println(Integer.toBinaryString(i));
//parseInt()
int a = Integer.parseInt("232");
System.out.println(a);
System.out.println(Integer.toBinaryString(a));
System.out.println(Integer.toHexString(a));
/**
* ~: 0-->1 1-->0
* 注意:00000001 ---> 11111110
*/
System.out.println(~a);
System.out.println(Integer.toHexString(~a));
int n;
int m;
/**
* | 或
*
* 0 | 0 = 0
* 0 | 1 = 1
* 1 | 0 = 1
* 1 | 1 = 0
*
* 常用于数据的拼接
*/
// n = 00000000 00000000 00000000 10100010
// m = 00000000 00000000 10111000 00000000
// i = 00000000 00000000 10111000 10100010
n = 0xa2;
m = 0xb800;
i = n | m; // 0xb8a2;
System.out.println(Integer.toHexString(i));
/**
* & 与
*
* 0 & 0 = 0
* 0 & 1 = 0
* 1 & 0 = 0
* 1 & 1 = 1
*
* 常用语拆分截取数据
*
* n = 00000000 00000000 00110100 10110101
* m = 00000000 00000000 00000000 11111111
* i = 00000000 00000000 00000000 10110101
*/
n = 0x34b5;
m = 0xff;
i = n & m; //0xb5;
System.out.println(Integer.toHexString(i));
/**
* >>> 逻辑右移
* n = 01010001 11000000 00000010 01011111
* n>>>1 = 001010001 11000000 00000010 0101111 1(右移后去掉,高位补0)
*
* n = 10100000 10110101 00101100 00100010
* c1 = 11111111 00000000 00000000 00000000
* c2 = 00000000 11111111 00000000 00000000
* c3 = 00000000 00000000 11111111 00000000
* c4 = 00000000 00000000 00000000 11111111
*/
int b1,b2,b3,b4;
n = 0xa0b52c22;
//截取
//拆分成byte
b1 = (n>>24) & 0xff;
b2 = (n>>16) & 0xff;
b3 = (n>>8) & 0xff;
b4 = n & 0xff;
System.out.println(Integer.toHexString(b1));
System.out.println(Integer.toHexString(b2));
System.out.println(Integer.toHexString(b3));
System.out.println(Integer.toHexString(b4));
//拼接
//byte组合成int
n = b4 | (b3<<8) | (b2<<16) | (b1<<24);
System.out.println(Integer.toHexString(n));
/**
* >>:正数的时候高位为0 >>补0
* 负数的时候高位为1 >>补1
* 以0开头的肯定是正数,以1开头的肯定是负数
*/
/**
* <<:左移
* 10进制中移动一位相当于源数据*10
* 2进制中移动一位相当于源数据*2
* 2<<1 = 2*2
* 2<<2 = 2*4 = 2*(2*2)
* 2<<3 = 2*8 = 2*(2*2*2)
* 20<<1 = 20*2
* 20<<2 = 20*4 = 20*(2*2)
*
* 位移n,相当于2的n次幂
*/
System.out.println(2<<3); //2*2*2*2=16
System.out.println(50<<4); //50*2*2*2*2=800
}
}
进制转换
- 字节转10进制
直接使用(int)类型转换。
/*
* 字节转10进制
*/
public static int byte2Int(byte b){
int r = (int) b;
return r;
}
- 10进制转字节
直接使用(byte)类型转换。
/*
* 10进制转字节
*/
public static byte int2Byte(int i){
byte r = (byte) i;
return r;
}
- 字节数组转16进制字符串
对每一个字节,先和0xFF做与运算,然后使用Integer.toHexString()函数,如果结果只有1位,需要在前面加0
/*
* 字节数组转16进制字符串
*/
public static String bytes2HexString(byte[] b) {
String r = "";
for (int i = 0; i < b.length; i++) {
String hex = Integer.toHexString(b[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
r += hex.toUpperCase();
}
return r;
}
- 16进制字符串转字节数组
这个比较复杂,每一个16进制字符是4bit,一个字节是8bit,所以两个16进制字符转换成1个字节,对于第1个字符,转换成byte以后左移4位,然后和第2个字符的byte做或运算,这样就把两个字符转换为1个字节。
/*
* 字符转换为字节
*/
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
/*
* 16进制字符串转字节数组
*/
public static byte[] hexString2Bytes(String hex) {
if ((hex == null) || (hex.equals(""))){
return null;
}
else if (hex.length()%2 != 0){
return null;
}
else{
hex = hex.toUpperCase();
int len = hex.length()/2;
byte[] b = new byte[len];
char[] hc = hex.toCharArray();
for (int i=0; i<len; i++){
int p=2*i;
b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p+1]));
}
return b;
}
}
- 字节数组转字符串
直接使用new String()
/*
* 字节数组转字符串
*/
public static String bytes2String(byte[] b) throws Exception {
String r = new String (b,"UTF-8");
return r;
}
- 字符串转字节数组
直接使用getBytes()。
/*
* 字符串转字节数组
*/
public static byte[] string2Bytes(String s){
byte[] r = s.getBytes();
return r;
}
- 16进制字符串转字符串
先转换成byte[],再转换成字符串。
/*
* 16进制字符串转字符串
*/
public static String hex2String(String hex) throws Exception{
String r = bytes2String(hexString2Bytes(hex));
return r;
}
- 字符串转16进制字符串
先转换为byte[],再转换为16进制字符串。
/*
* 字符串转16进制字符串
*/
public static String string2HexString(String s) throws Exception{
String r = bytes2HexString(string2Bytes(s));
return r;
}
main函数:
public static void main(String[] args) throws Exception{
byte b1 = (byte) 45;
System.out.println("1.字节转10进制:" + byte2Int(b1));
int i = 89;
System.out.println("2.10进制转字节:" + int2Byte(i));
byte[] b2 = new byte[]{(byte)0xFF, (byte)0x5F, (byte)0x6, (byte)0x5A};
System.out.println("3.字节数组转16进制字符串:" + bytes2HexString(b2));
String s1 = new String("1DA47C");
System.out.println("4.16进制字符串转字节数组:" + Arrays.toString(hexString2Bytes(s1)));
System.out.println("5.字节数组转字符串:" + bytes2String(b2));
System.out.println("6.字符串转字节数组:" + Arrays.toString(string2Bytes(s1)));
System.out.println("7.16进制字符串转字符串:" + hex2String(s1));
String s2 = new String("Hello!");
System.out.println("8.字符串转16进制字符串:" + string2HexString(s2));
}
运行结果:
字节转10进制:45
.10进制转字节:89
.字节数组转16进制字符串:FF5F065A
.16进制字符串转字节数组:[29, -92, 124]
.字节数组转字符串:?_Z
.字符串转字节数组:[49, 68, 65, 52, 55, 67]
.16进制字符串转字符串:?|
.字符串转16进制字符串:48656C6C6F21
定位问题原因*
根据原因思考问题解决方案*
实践验证方案有效性*
提交验证结果