大数四则运算(加、减、乘、整除、求余)

概述:

    实现参与运算的数或者运算结果中,长度最大的一个数的位数,不超过String类型最大长度的大数的四则运算。

实现思路:

    加法:模拟笔算的过程,逐位运算;
    减法:先比较大小,让较大的数作为被减数(被减数-减数=差),再仿照加法运算;
    乘法:和加法类似,逐位运算;
    除法(整除):除法比较复杂一点,是用连续相减实现。不过用被除数逐个减除数显然太慢了,我们首先得到被除数和除数相差的位数n,令temp为除数乘以10的n次方,使满足被除数×0.1≤temp≤被除数,用被除数减去temp,然后n--,重新得到temp,重复上面过程,直至n为0;
    求余:和整除的思路一样,只是最后返回的值不一样。

public class BigNumber {
	private static BigNumber self = new BigNumber();

	/**
	 * add
	 */
	public String add(String string1, String string2) {
		string1 = self.getStandardString(string1);
		string2 = self.getStandardString(string2);

		int len1 = string1.length();
		int len2 = string2.length();
		int sumLen = Math.max(len1, len2) + 1;
		int[] array1 = new int[sumLen];
		int[] array2 = new int[sumLen];
		int[] sum = new int[sumLen];
		int temp = 0;
		// 字符串转数组
		for (int i = len1 - 1, j = 0; i >= 0; i--, j++) {
			array1[j] = (int) string1.charAt(i) - '0';
		}
		// 字符串转数组
		for (int i = len2 - 1, j = 0; i >= 0; i--, j++) {
			array2[j] = (int) string2.charAt(i) - '0';
		}
		// 求和
		for (int i = 0; i < sumLen; i++) {
			temp = sum[i] + array1[i] + array2[i];
			if (temp >= 10) {
				temp = temp - 10;
				sum[i + 1] = 1;
			}
			sum[i] = temp;
		}
		StringBuilder result = new StringBuilder();
		boolean flag = true;
		for (int i = sumLen - 1; i >= 0; i--) {
			if (flag) {
				if (sum[i] == 0) {
					continue;
				} else {
					flag = false;
				}
			}
			result.append(sum[i]);
		}
		return result.toString();
	}

	/**
	 * sub
	 */
	public String sub(String string1, String string2) {
		string1 = self.getStandardString(string1);
		string2 = self.getStandardString(string2);

		int len1 = string1.length();
		int len2 = string2.length();
		StringBuilder result = new StringBuilder();
		// 将大的字符串放前面
		int relation = self.getThen(string1, string2);
		if (relation == -1) {
			String tempString = string1;
			string1 = string2;
			string2 = tempString;
			result.append("-");
		} else if (relation == 0) {
			return "0";
		}

		len1 = string1.length();
		len2 = string2.length();
		int sumLen = Math.max(len1, len2);
		int[] array1 = new int[sumLen];
		int[] array2 = new int[sumLen];
		int[] sum = new int[sumLen];
		int temp = 0;
		// 字符串转数组
		for (int i = len1 - 1, j = 0; i >= 0; i--, j++) {
			array1[j] = (int) string1.charAt(i) - '0';
		}
		// 字符串转数组
		for (int i = len2 - 1, j = 0; i >= 0; i--, j++) {
			array2[j] = (int) string2.charAt(i) - '0';
		}
		// 求差
		for (int i = 0; i < sumLen; i++) {
			temp = sum[i] + array1[i] - array2[i];
			if (temp < 0) {
				temp = temp + 10;
				sum[i + 1] = -1;
			}
			sum[i] = temp;
		}
		boolean flag = true;
		for (int i = sumLen - 1; i >= 0; i--) {
			if (flag) {
				if (sum[i] == 0) {
					continue;
				} else {
					flag = false;
				}
			}
			result.append(sum[i]);
		}
		return result.toString();
	}

	/**
	 * mul
	 */
	public String mul(String string1, String string2) {
		string1 = self.getStandardString(string1);
		string2 = self.getStandardString(string2);

		int len1 = string1.length();
		int len2 = string2.length();
		int[] array1 = new int[len1];
		int[] array2 = new int[len2];
		int[][] sum = new int[len2][len1 + 1];
		int temp = 0;
		// 字符串转数组
		for (int i = len1 - 1, j = 0; i >= 0; i--, j++) {
			array1[j] = (int) string1.charAt(i) - '0';
		}
		// 字符串转数组
		for (int i = len2 - 1, j = 0; i >= 0; i--, j++) {
			array2[j] = (int) string2.charAt(i) - '0';
		}
		// 求积
		for (int i = 0; i < len2; i++) {
			for (int j = 0; j < len1; j++) {
				temp = array2[i] * array1[j] + sum[i][j];
				sum[i][j] = temp % 10;
				sum[i][j + 1] = temp / 10;
			}
		}
		String result = null;
		StringBuilder midResult = new StringBuilder();
		StringBuilder tempResult;
		for (int i = len1; i >= 0; i--) {
			midResult.append(sum[0][i]);
		}

		result = midResult.toString();
		if (len2 == 1) {
			return self.add(midResult.toString(), "0");
		}
		for (int i = 1; i < len2; i++) {
			tempResult = new StringBuilder();
			for (int j = len1; j >= 0; j--) {
				tempResult.append(sum[i][j]);
			}
			for (int k = 0; k < i; k++) {
				tempResult.append("0");
			}
			result = self.add(result, tempResult.toString());
		}
		return result;
	}

	/**
	 * div
	 */
	public String div(String string1, String string2) throws Exception {
		string1 = self.getStandardString(string1);
		string2 = self.getStandardString(string2);

		if (string2.equals("0")) {
			Exception exception = new ArithmeticException();
			throw exception;
		}
		int len1 = string1.length();
		int len2 = string2.length();

		int relation = self.getThen(string1, string2);
		if (relation == -1) {
			return "0";
		} else if (relation == 0) {
			return "1";
		}

		int distance = len1 - len2;
		int count = 0;
		StringBuilder midNum;
		String midString;
		String midResult;
		String result = "0";
		while (distance >= 0) {
			StringBuilder coe = new StringBuilder("1"); // 倍数
			for (int i = 0; i < distance; i++) { // *10
				coe.append("0");
			}

			midNum = new StringBuilder();
			midNum.append(string2);
			for (int i = 0; i < distance; i++) { // *10
				midNum.append("0");
			}
			midString = midNum.toString(); // 减数
			if (self.getThen(midString, string1) == 1) {
				distance--;
				continue;
			}

			count = 0;
			while (self.getThen(midString, string1) < 1) {
				string1 = self.sub(string1, midString);
				count++;
			}
			midResult = self.mul(coe.toString(), String.valueOf(count));
			result = self.add(result, midResult);

			distance--;
		}

		return result;
	}

	/**
	 * mod
	 */
	public String mod(String string1, String string2) throws Exception {
		string1 = self.getStandardString(string1);
		string2 = self.getStandardString(string2);

		if (string2.equals("0")) {
			Exception exception = new ArithmeticException();
			throw exception;
		}
		int len1 = string1.length();
		int len2 = string2.length();

		int relation = self.getThen(string1, string2);
		if (relation == -1) {
			return string1;
		} else if (relation == 0) {
			return "0";
		}

		int distance = len1 - len2;
		StringBuilder midNum;
		String midString;
		String result = "0";
		while (distance >= 0) {
			StringBuilder coe = new StringBuilder("1"); // 倍数
			for (int i = 0; i < distance; i++) { // *10
				coe.append("0");
			}

			midNum = new StringBuilder();
			midNum.append(string2);
			for (int i = 0; i < distance; i++) { // *10
				midNum.append("0");
			}
			midString = midNum.toString(); // 减数
			if (self.getThen(midString, string1) == 1) {
				distance--;
				continue;
			}

			while (self.getThen(midString, string1) < 1) {
				string1 = self.sub(string1, midString);
			}
			result = string1;

			distance--;
		}

		return result;
	}

	/**
	 * get relation ; str1 > str2 -> 1 ; str1 = str2 -> 0 ; str1 < str2 -> -1 ;
	 */
	private int getThen(String string1, String string2) {
		string1 = self.getStandardString(string1);
		string2 = self.getStandardString(string2);

		int len1 = string1.length();
		int len2 = string2.length();

		if (len1 < len2) {
			return -1;
		} else if (len1 > len2) {
			return 1;
		} else if (len1 == len2) {
			for (int i = 0; i < len1; i++) {
				if (string1.charAt(i) == string2.charAt(i)) {
					continue;
				} else if (string1.charAt(i) > string2.charAt(i)) {
					return 1;
				} else
					return -1;
			}
		}
		return 0;
	}

	/**
	 * return standard string
	 */
	private String getStandardString(String string) {
		string = string.trim();
		StringBuilder stringBuilder = new StringBuilder();
		char singleChar;
		boolean flag = true;
		// 剥离非数字字符
		for (int index = 0; index < string.length(); index++) {
			singleChar = string.charAt(index);
			if (singleChar <= '9' && singleChar >= '0') {
				stringBuilder.append(singleChar);
			}
		}
		string = stringBuilder.toString();
		stringBuilder = new StringBuilder();
		// 剥离开头的数字0
		for (int index = 0; index < string.length(); index++) {
			singleChar = string.charAt(index);
			if (flag) {
				if (singleChar == '0') {
					continue;
				} else {
					flag = false;
				}
			}
			stringBuilder.append(singleChar);
		}
		String result = stringBuilder.toString();
		if (result == null || result.length() == 0) {
			return "0";
		}
		return result;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值