04-请用移位的方式打印出一个十进制整数的十六进制形式(JDK源码)
01-需求:
- 请用移位的方式打印出一个十进制整数的十六进制形式。
提示:
按每4个二进制位对整数进行移位和去高位处理,得到的结果就是十六进制数的一位,
然后按下面三种方式之一(作为作业,要求每种方式都用到)计算出一个十六进制数值对应的十六进制形式:
1)0-9之间的数值直接加上字符’0’,9以上的数值减去10以后再加上字符’A’
2)定义一个数组,其中包含0-F这些字符,然后用要计算的数值作为数组的索引号,即可获得其对应的十六进制数据。
3)Character.forDigit静态方法可以将一个十六进制的数字转变成其对应的字符表示形式,例如,根据数值15返回字符’F’。
02-思路
1. 掩码mask的计算。shift参数用于区分不同进制,比如二进制的shift=1,mask=1;八进制的shift=3,mask=7;十六进制的shift=4,mask=15。
2. 右移使用的是>>>而不是>>。位运算中的右移分为算术右移(>>)和逻辑右移(>>>)。在进行算术右移时,最高位补符号位;而在进行逻辑右移时,最高位补0。如果这里使用的算术右移,那么对于像-1这样的负数,不论进行多少次右移操作都不可能变成0,所以会造成死循环。
3. 使用的是do-while而不是while。这是一个极其重要的细节,如果使用的是while,那么对于i=0的场景则会返回空字符串。
4. 算术左移(<<)、右移(>>)主要用来进行有符号数的倍增、减半;
逻辑左移(<<<)、右移(>>>)主要用来进行无符号数的倍增、减半。(左移都是低位补0,算数右移高位补符号位,逻辑右移高位补0)
5.
二进制:
public static String toBinaryString(int i) {
return toUnsignedString(i, 1);
}
八进制:
public static String toOctalString(int i) {
return toUnsignedString(i, 3);
}
十六进制:
public static String toHexString(int i) {
return toUnsignedString(i, 4);
}
补充:每个IP地址都由网络号和主机号两部分组成,通过子网掩码(subnet mask)区分网络号和主机号(子网掩码:255.0.0.0;255二进制数1111)
03-代码:
package com.eleven;
/** * 请用移位的方式打印出一个十进制整数的十六进制形式。 * 提示: * 按每4个二进制位对整数进行移位和去高位处理,得到的结果就是十六进制数的一位, * 然后按下面三种方式之一(作为作业,要求每种方式都用到)计算出一个十六进制数值对应的十六进制形式: * 1)0-9之间的数值直接加上字符'0',9以上的数值减去10以后再加上字符'A' * 2)定义一个数组,其中包含0-F这些字符,然后用要计算的数值作为数组的索引号,即可获得其对应的十六进制数据。 * 3)Character.forDigit静态方法可以将一个十六进制的数字转变成其对应的字符表示形式,例如,根据数值15返回字符'F'。 * * @author sywangu * */
public class FourDemo {
// digits:数字,定义一个char类型的常量
final static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'A', 'B', 'C', 'D', 'E', 'F'};
private static String toHexString(int i) {
char[] buf = new char[32]; // 创建一个32位的缓存数组
int charPos = 32; // 当数组中有余数时,方便从char数组中取出数据
int radix = 1 << 4; // radix(进制)表示1左移4位,二进制就变成10000,十进制也就是16.
int mask = radix - 1; // 16进制中的mask为15
do {
// i表示我们传入的值,mask表示15
buf[--charPos] = digits[i & mask]; // i & mask的目的就是取i的最后4位,然后在digits表单中取到相应的十六进制字符。
// 新建数组大小时[]填32,但是在数组赋值时[]填0~31
i >>>= 4; // 逻辑右移,然后进入循环,直到i为0
} while (i != 0); // 当i为0时,跳出循环
// 循环完毕上面后就相当于把传进来的i变成二进制字符串并且放到buf数组里
return new String(buf, charPos, (32 - charPos));
}
public static void main(String[] args) {
int i = 15; // 我们传入i的值为15
System.out.println(toHexString(i)); // 打印出来的值是F
}
}
还没有评论,来说两句吧...