程序员的数学基础课——手写实现十进制转二进制

前言:编程从动手开始!

之前看资料,都是看看完事,较少动手实践,最近开始学极客时间课程——程序员的数学基础课,觉得实践一下。

本文主要通过两种方式实现十进制转二进制:1. 使用 BigInteger ;2. 手写实现。代码如下:

1、使用BigInteger实现十进制和二进制直接相互转换

package match_programing;

import java.math.BigInteger;

/**
 * 十进制和二进制相互转换
 * 
 * @author Administrator
 *
 */
public class IntegerBinary {

	/**
	 *  十进制转换为二进制
	 *  
	 * @param integer
	 *         Integer 输入的十进制数
	 * @return binaryString
	 *         十进制转换后的二进制字符串
	 */
	public String integer2Binary(String integer) {
		
		BigInteger bi = new BigInteger(integer);    // 转换成 BigInteger 类型,默认是十进制
		String binaryString = bi.toString(2);       // 参数 2 指定的是转换成二进制
		
		return binaryString;
	}
	
	/**
	 * 二进制字符串转换为十进制字符串
	 * 
	 * @param binaryString
	 *        二进制字符串
	 * @return integerString
	 *         十进制字符串
	 */
	public int  binary2IntegerString(String binaryString) {
		
		BigInteger bigInteger = new BigInteger(binaryString, 2);    // 转换成 BigInteger 类型,参数 2 指定的是二进制
		int integer = Integer.parseInt(binaryString.toString());    // 默认转换成十进制
		
		return integer;
	}
	
	/**
	 * 测试
	 */
	public static void main(String[] args) {
		
		int a = 53;
		String b = "110101";
		
		IntegerBinary integerBinary = new IntegerBinary();
	    System.out.println(integerBinary.integer2Binary(String.valueOf(a)));
	    System.out.println(integerBinary.binary2IntegerString(b));
		
	}
	
}

2、手写实现十进制转二进制

package match_programing;

/**
 * 不使用 BigInteger,自己实现十进制转二进制
 * 提示: 使用二进制的移位和按位逻辑操作来实现
 * 
 * 负整数转换为二进制要点:取反加一
 *   1. 将该负数对应的正数先转换成二进制
 *   2. 将转换后的二进制数取反,然后加 1
 * 
 * @author Administrator
 *
 */
public class Integer2Binary {
	
	/**
	 * 不使用 BigInteger,实现十进制转二进制,同时,支持负数的进制转换
	 * @param integer
	 * @return
	 */
	public String integer2BinaryString(int integer) {
		if(integer == 0) {    // 如果输入数字为0,则直接返回
			return "0";
		}
		
		boolean negative = integer < 0 ? true : false;    // 标志位,用于记录输入是否是负数
		int num;    // 用于进行计算的数字,大于0
		if (negative) {
			num = -integer;
		}else {
			num = integer;
		}
		
		StringBuilder sb = new StringBuilder();    // 存储取余过程中产生的余数
		while(num > 0) {
			int tmp = num % 2;    // 取余
			num = num >>> 1;    // 算术右移
			sb.append(tmp);
		}
		
		int len = sb.length();
		if (negative && len < 64) {    // 以 64 位系统为例,不足的长度需要全部补0
			for (int i = 0; i < 64 - len; i++) {
				sb.append('0');
			}
		}    
		String binaryString = sb.reverse().toString();   // 获取 num 对应的二进制码
		
		if(negative) {
			binaryString = dealNegativeBinary(binaryString);
		}
		
		
		return binaryString;
	}
	
	/**
	 * 对负数的二进制数,进行安位取反
	 * 
	 * @param binaryString
	 * @return
	 */
	public String dealNegativeBinary(String binaryString) {
		
		StringBuilder sb = new StringBuilder();
		char[] chars = binaryString.toCharArray();
		for ( char c : chars) {
			if (c == '1') {
				sb.append('0');
			}else {
				sb.append('1');
			}
		}
		return negativeAdd1(sb.toString());
	}
	
	/**
	 * 对按位取反后的值执行加一操作
	 * 
	 * @param binaryString
	 * @return
	 */
	public String negativeAdd1(String binaryString) {
		StringBuilder sb = new StringBuilder(binaryString);
		String calculateString = sb.reverse().toString();    // 对需要进行加一操作的二进制字符串取反,从低位开始操作
		char[] arrays = calculateString.toCharArray();
		if (arrays[0] == '0') {    // 如果最低位是 0,直接加一后返回
			arrays[0] = '1';
			StringBuilder sBuilder = new StringBuilder(new String(arrays));
			return sBuilder.reverse().toString();
		}
		// 需要进行循环进位计算
		boolean append = true;    // 进位标志
		StringBuilder stringBuilder = new StringBuilder('0');    // 用于添加执行加一后的二进制元素
	    int i = 1;
		for (; i < arrays.length; i++) {
			if (arrays[i] == '1') {
				stringBuilder.append('0');
			}else {
				stringBuilder.append('1');
				append = false;
				break;
			}
		}
		
		if (append && i == arrays.length) {    // 如果到了最后仍存在进位,则发生了溢出,否则把剩余的值 append 到 stringBuilder
			System.out.println("数据溢出");
			return "0";
		}else {
			for (; i < arrays.length; i++) {
				stringBuilder.append(arrays[i]);
			}
		}
		
		return stringBuilder.reverse().toString();
	}
	
	
	/**
	 * 测试
	 */
	public static void main(String[] args) {
		Integer2Binary integer2Binary = new Integer2Binary();
		
		int a = 53;   // 110101
		int b = -53;  // 1...(56个1)11001011
		System.out.println(integer2Binary.integer2BinaryString(a));
		System.out.println(integer2Binary.integer2BinaryString(b));
	}

}

        上面代码执行是通过的。只有在自己实现的过程中,才会发现很多问题是读文章,粘贴别人的代码时不会注意到的,或者想不到的,比如对于负数,第一次测试时,就发现在获取 负数对应正数 的二进制码后,忘了将余下的位数补0,这样获得的结果就是错误的。

        目前的实现还很原始,感觉可以优化的地方还很多,后面有时间的话,通过对比BigInteger的源码,再进一步优化一下。

        第二部分纯属按照当前自己能够想到的方面进行实现,如果错误,欢迎大家指正。

你可能感兴趣的:(Java,数据结构与算法)