进制转换之原理实现(Java)

进制转换之原理实现(Java)

1、将整数字符串转换为整数

  整数字符串是由符号+数字组成,radix进制的范围是0 ~ radix-1。

  原理:先识别符号,再通过radix进制幂的展开式获得整数字符串的整数值(如果将进制radix提取公因数会更明显,这里就不提取了,嘿嘿)。

例如:

  

代码如下:

/**
	 * @param s
	 *            将s按十进制转换为整数
	 * @return 省略radix 默认是10进制
	 * @throws NumberFormatException
	 */
	public static int parseInt(String s) throws NumberFormatException {
		return MyString.parseInt(s, 10);
	}

	/**
	 * @param s
	 * @param radix
	 * @return 将字符串s转化为radix进制整数
	 * @throws NumberFormatException
	 */
	public static int parseInt(String s, int radix)
			throws NumberFormatException {

		if (s == null) {
			throw new NumberFormatException("null");
		}
		if (radix < 2 || radix > 16) {
			throw new NumberFormatException("radix=" + radix + ",进制超出2~16范围");
		}
		int value = 0, i = 0;
		int sign = s.charAt(0) == '-' ? -1 : 1;// 符号位,记住正负数标记
		if (s.charAt(0) == '+' || s.charAt(0) == '-') { // 跳过符号位
			if (s.length() == 1) {// 如果字符串s只有符号位”+"、"-",则抛出异常
				throw new NumberFormatException();
			} else
				// 否则,i记住当前字符序号
				i++;
		}

		while (i < s.length()) {
			char ch = s.charAt(i++);
			// 如果2<=radix<=16,radix进制要识别0~radix-1的数字
			if (ch >= '0' && ch - '0' < radix) {
				value = value * radix + ch - '0';
			} 
			//如果11<=radix<=16,radix识别从'a'/'A'开始的radix-10个字母表示的整数
			else if (radix > 10 && radix <= 16 && ch >= 'a'
					&& ch - 'a' < radix - 10) {
				value = value * radix + ch - 'a' + 10;
			} else if (radix > 10 && radix <= 16 && ch >= 'A'
					&& ch - 'A' < radix - 10) {
				value = value * radix + ch - 'A' + 10;
			} else {
				throw new NumberFormatException(radix + "进制整数不能识别" + ch);
			}
		}

		return value * sign;
	}

2、将整数转换为radix进制字符串

  计算机采用二进制补码存储整数并进行运算,整数的二进制补码以最高位表示符号,0表示正数,1表示负数。

获得十六进制补码字符串,采用位运算(除16取余法),算法图解如下:

  一个十六进制数是4位二进制,十进制数 & 15得出的结果是十六进制数的个位数,十六进制数 & f得出的结果也是十六进制数的个位数,之后再右移4位,得到十六进制数下一位数字,如此循环(int是32位,循环8次)。


算法原理描述如下:

(1)采用字符数组buffer[]存储各位数字字符,避免频繁字符串的连接运算,提高算法效率。

(2)设int value是需要转换的整数,由于十六进制的最大数是15,将value&15得到value的十六进制个位(即二进制最低4位),存储在buffer字符数组的最后一位buffer[i]中,i=buffer.length-1。

(3)value>>=4,表示将value右移二进制4位,即十六进制一位,高位补0,重复执行(2)操作8次。这样就可以得到一个整数的十六进制补码字符串。

  上述的算法适用于二、四、八、十六进制,每次value & radix-1获得个位,再分别右移1、2、3、4位二进制。


代码如下:

/**
	 * @param value
	 * @return 转换为十六进制
	 */
	public static String toHexString(int value) {
		char[] buffer = new char[8];// 一个int(32位)有8个十六进制位
		for (int i = buffer.length - 1; i >= 0; i--) {
			int bit = value & 15;
			buffer[i] = (char) (bit <= 9 ? bit + '0' : bit + 'a' - 10);
			value >>= 4;//右移4位
		}

		return new String(removePreZero(buffer));
	}

	/**
	 * @param value
	 * @return 转换二进制
	 */
	public static String toBinaryString(int value) {
		char[] buffer = new char[32];//一个int有32位二进制
		for (int i = buffer.length - 1; i >= 0; i--) {
			int bit = value & 1;
			buffer[i] = (char) (bit + '0');
			value >>= 1;//右移1位
		}
		return new String(removePreZero(buffer));
	}

	/**
	 * @param value
	 * @return 转换为八进制
	 */
	public static String toOctalString(int value) {
		char[] buffer = new char[10];//一个int是32位二进制,一个八进制是3位二进制数,那么一个int保存10个八进制
		for (int i = buffer.length - 1; i >= 0; i--) {
			int bit = value & 7;
			buffer[i] = (char) (bit + '0');
			value >>= 3;
		}
		return new String(removePreZero(buffer));
	}

	/**
	 * @param value
	 * @return 去除每个数前面无用的0
	 */
	public static char[] removePreZero(char[] buffer) {
		char[] temp = null;
		for (int i = 0; i < buffer.length; i++) {
			if (buffer[i] != '0') {
				temp = new char[buffer.length - i];
				for (int j = 0; j < temp.length; j++) {
					temp[j] = buffer[i++];
				}
				break;
			}
		}
		return temp;
	}


 


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值