04-请用移位的方式打印出一个十进制整数的十六进制形式(JDK源码)

淡淡的烟草味﹌ 2021-09-23 17:28 85阅读 0赞

01-需求:

  • 请用移位的方式打印出一个十进制整数的十六进制形式。
  • 提示:

    按每4个二进制位对整数进行移位和去高位处理,得到的结果就是十六进制数的一位,

    然后按下面三种方式之一(作为作业,要求每种方式都用到)计算出一个十六进制数值对应的十六进制形式:

    1)0-9之间的数值直接加上字符’0’,9以上的数值减去10以后再加上字符’A’

    2)定义一个数组,其中包含0-F这些字符,然后用要计算的数值作为数组的索引号,即可获得其对应的十六进制数据。

    3)Character.forDigit静态方法可以将一个十六进制的数字转变成其对应的字符表示形式,例如,根据数值15返回字符’F’。

02-思路

  1. 1. 掩码mask的计算。shift参数用于区分不同进制,比如二进制的shift=1mask=1;八进制的shift=3mask=7;十六进制的shift=4mask=15
  2. 2. 右移使用的是>>>而不是>>。位运算中的右移分为算术右移(>>)和逻辑右移(>>>)。在进行算术右移时,最高位补符号位;而在进行逻辑右移时,最高位补0。如果这里使用的算术右移,那么对于像-1这样的负数,不论进行多少次右移操作都不可能变成0,所以会造成死循环。
  3. 3. 使用的是do-while而不是while。这是一个极其重要的细节,如果使用的是while,那么对于i=0的场景则会返回空字符串。
  4. 4. 算术左移(<<)、右移(>>)主要用来进行有符号数的倍增、减半;
  5. 逻辑左移(<<<)、右移(>>>)主要用来进行无符号数的倍增、减半。(左移都是低位补0,算数右移高位补符号位,逻辑右移高位补0)
  6. 5.
  7. 二进制:
  8. public static String toBinaryString(int i) {
  9. return toUnsignedString(i, 1);
  10. }
  11. 八进制:
  12. public static String toOctalString(int i) {
  13. return toUnsignedString(i, 3);
  14. }
  15. 十六进制:
  16. public static String toHexString(int i) {
  17. return toUnsignedString(i, 4);
  18. }
  19. 补充:每个IP地址都由网络号和主机号两部分组成,通过子网掩码(subnet mask)区分网络号和主机号(子网掩码:255.0.0.0;255二进制数1111)

03-代码:

  1. package com.eleven;
  2. /** * 请用移位的方式打印出一个十进制整数的十六进制形式。 * 提示: * 按每4个二进制位对整数进行移位和去高位处理,得到的结果就是十六进制数的一位, * 然后按下面三种方式之一(作为作业,要求每种方式都用到)计算出一个十六进制数值对应的十六进制形式: * 1)0-9之间的数值直接加上字符'0',9以上的数值减去10以后再加上字符'A' * 2)定义一个数组,其中包含0-F这些字符,然后用要计算的数值作为数组的索引号,即可获得其对应的十六进制数据。 * 3)Character.forDigit静态方法可以将一个十六进制的数字转变成其对应的字符表示形式,例如,根据数值15返回字符'F'。 * * @author sywangu * */
  3. public class FourDemo {
  4. // digits:数字,定义一个char类型的常量
  5. final static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
  6. '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  7. private static String toHexString(int i) {
  8. char[] buf = new char[32]; // 创建一个32位的缓存数组
  9. int charPos = 32; // 当数组中有余数时,方便从char数组中取出数据
  10. int radix = 1 << 4; // radix(进制)表示1左移4位,二进制就变成10000,十进制也就是16.
  11. int mask = radix - 1; // 16进制中的mask为15
  12. do {
  13. // i表示我们传入的值,mask表示15
  14. buf[--charPos] = digits[i & mask]; // i & mask的目的就是取i的最后4位,然后在digits表单中取到相应的十六进制字符。
  15. // 新建数组大小时[]填32,但是在数组赋值时[]填0~31
  16. i >>>= 4; // 逻辑右移,然后进入循环,直到i为0
  17. } while (i != 0); // 当i为0时,跳出循环
  18. // 循环完毕上面后就相当于把传进来的i变成二进制字符串并且放到buf数组里
  19. return new String(buf, charPos, (32 - charPos));
  20. }
  21. public static void main(String[] args) {
  22. int i = 15; // 我们传入i的值为15
  23. System.out.println(toHexString(i)); // 打印出来的值是F
  24. }
  25. }

发表评论

表情:
评论列表 (有 0 条评论,85人围观)

还没有评论,来说两句吧...

相关阅读