大數四則運算(加、減、乘、整除、求餘)

概述:

    實現參與運算的數或者運算結果中,長度最大的一個數的位數,不超過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;
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章