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=152. 右移使用的是>>>而不是>>。位运算中的右移分为算术右移(>>)和逻辑右移(>>>)。在进行算术右移时,最高位补符号位;而在进行逻辑右移时,最高位补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
		}
}
发布了90 篇原创文章 · 获赞 284 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_41293896/article/details/103993064