/**我的思路是先将输入的10进制数转换成2进制,再讲2进制转成16进制*/
public static byte[] int10ToInt16Convert(Integer source) {
return int2ToInt16Convert(
int10ToInt2Convert(source)
);
}
/**
*将对比数的首位1每次右移一位,与原int数进行按位与运算,由于对比数只有一位为1,
*所以原int数中只有与当前对比数1所在位对应的位上是1,整个与运算结果才非0
*而i就是当前的位数,所以循环后就可以得出每一位的2进制数了
*/
private final static int PAN_DING_FU = 0x80000000; //16进制的对比数,二进制为1000 0000 0000 0000 0000 0000 0000 000
private final static int INT_LENGTH = 32; //int类型的长度为32位
private static byte[] int10ToInt2Convert(Integer source) {
byte[] target = new byte[INT_LENGTH]; //将目标2进制的每一位存入byte数
for (int i = PANG_DING_FU, j = 0; i != 0; i >>>= 1) {
target[j] = (byte) ((source & i) == 0 ? 0 : 1);
j++;
}
return target;
}
private static byte[] int2ToInt16Convert(byte[] source) {
byte[] target = new byte[8]; // 32位的2进制对应的16进制是8位(4位为一组)
int i = 0;
for (i = 3; i < INT_LENGTH; i += 4) { //4位为一组,每次递增4 ,从3开始,0123位一组,4567为一组,以此规则遍历2进制数组参数
byte result = 0; //内层循环是为了把每组二进制转换成(0-16)的10进制((abcd)2 = (a*2^3+b*2^2+c*2+d))
for (int j = 3; j >= 0; j--) {
byte b = source[i - j]; //由于每次的i都是当前组最大的下标,所以采用减法倒叙输出 以0123 组为例 分别是3-3->0 ,3-1->2,3-2->1,3-3->0;
result += b << j;
}
target[(i) / 4] = convert16Token(result); //(见下一节)
// 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15->
// 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f
}
return target;
}
private static byte convert16Token(byte source) {
if (source > 15 || source < 0)
throw new IllegalArgumentException("只接受0-15的值");
if (source >= 0 && source < 10) //如果0到10原样输出
return source;
if (source >= 10 && source < 16) { //10到16转化成相应的字母
byte target = 0;
switch (source) {
case 10:
target = 'a'; //注入,这里byte存字母存的是其ASCII码
break;
case 11:
target = 'b';
break;
case 12:
target = 'c';
break;
case 13:
target = 'd';
break;
case 14:
target = 'e';
break;
case 15:
target = 'f';
break;
}
return target;
}
return -1;
}
public static void main(String[] args) {
System.out.println("请输入要转换的数字,按回车开始转换,按-1结束:");
Scanner scanner = new Scanner(System.in);
Integer source = scanner.nextInt();
while (source != -1) {
print(int10ToInt16Convert(source)); //print方法打印16进制的byte数组
source = scanner.nextInt();
}
}
/**这里如果需要保存16进制的字符串可以将System.out.print换成StringBuiler进行拼接**/
private static void print(byte[] bytes) {
System.out.print("0x"); //16进制0x标识
boolean is_first = false;
for (byte b : bytes) {
if (b != 0&&!is_first) //第一个非0位之前的0都不输出
is_first = true; //用is_first做一个标志位
if (is_first) {
if (b < 10) //如果小于10原样输出
System.out.print(b + "");
else //否则转换为char字符输出
System.out.print((char) b + "");
}
}
}
最后附上测试结果
测试结果