Java模拟两个大整数的加法、乘法、除法
2017-03-14 17:52
435 查看
package ddd; import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class BigIntegerAddition { /** * * 问题:java实现两个大数相加,可能存在溢出。 如123456789 + 987654321 返回 1111111110 * * 解决办法: * 1.直接用BigInteger * * 2.模拟手算加法,进位相加(暂时没有考虑负数的情况),该类模拟两个大数的相加, 相乘,相除。至于相减,看了该类的相加就知道如何实现了。 * 该类中的加、乘、除的算法思路与人工的计算方式一致。虽然算法目的是达到了,但效率的话的确有待商榷,因为本人能力有限,实在是想不到更好的实现方式,还望 * 各位路过的高人指点!!!若有更好的实现方式,记得留言咯! */ public static void main(String[] args) { String x = "23456789"; String y = "987654321"; BigInteger a = new BigInteger(x); BigInteger b = new BigInteger(y); BigInteger c = a.add(b); System.out.println(c.toString()); System.out.println(add(x, y)); System.out.println(add("-100", "1")); System.out.println(add("-1000", "1")); System.out.println(add("-1", "1")); System.out.println(add("-17", "901")); System.out.println(add("1", "-100")); System.out.println(add("1", "-1000")); System.out.println(add("1", "-1")); System.out.println(add("901", "-17")); System.out.println(posMultiPos("556", "7")); System.out.println(posMultiPos("195", "5")); System.out.println(posMultiPos("919", "8")); System.out.println("--->" + trimPrefixedZero("0")); System.out.println(posMultiPos("99", "0")); System.out.println(divid("138", "12", 6)); System.out.println(divid("10", "3", 6)); } /** * 两个整数的加法运算,考虑正负数,由于减法可以转化为加法运算, * 所以本人并没有直接给出求大整数减法的算法 * @param x * @param y * @return */ public static String add(String x, String y) { if (isNullOrEmpty(x) || isNullOrEmpty(y)) { return null; } if (!isNumeric(x) || !isNumeric(y)) { return null; } if (x.equals("0")) { return y; } if (y.equals("0")) { return x; } if (x.charAt(0) == '-' && y.charAt(0) == '-') { x = x.substring(1); y = y.substring(1); return "-" + posAddPos(x, y); } else if (x.charAt(0) != '-' && y.charAt(0) != '-') { return posAddPos(x, y); } else if (x.charAt(0) == '-' && y.charAt(0) != '-') { return negAddPos(x, y); } else if (x.charAt(0) != '-' && y.charAt(0) == '-') { String tem = x; x = y; y = tem; return negAddPos(x, y); } return null; } /** * 一个负数与一个正数的加法 * @param x * @param y * @return */ public static String negAddPos(String x, String y) { if (x.charAt(0) != '-' || y.charAt(0) == '-') { throw new IllegalArgumentException("x必须是负数数,y必须是正数"); } // 判断x代表的负数的绝对值是否比正数y的绝对值大 boolean isAbsXLarger = false; x = x.substring(1); if (x.length() > y.length()) { isAbsXLarger = true; String tmp = x; x = y; y = tmp; } else if (x.length() == y.length()) { isAbsXLarger = isAbsXLarger(x, y); if (isAbsXLarger) { String tmp = x; x = y; y = tmp; } } x = addZeroToFirst(x, y.length()); int len = y.length(); int[] a = toIntArray(y); int[] b = toIntArray(x); int[] c = new int[len + 1]; for (int i = 0; i < len; i++) { int ac = a[len - 1 - i]; int bc = b[len - 1 - i]; if (ac - bc >= 0) { c[len - i] = ac - bc; } else { c[len - i] = (ac + 10) - bc; int r = 1; while ((len - 1 - i - r) >= 0 && a[len - 1 - i - r] == 0) { a[len - 1 - i - r] = 9; r++; } a[len - 1 - i - r] = a[len - 1 - i - r] - 1; } } StringBuilder sb = new StringBuilder(); for (int i = 0; i <= len; i++) { sb.append(c[i]); } String z = trimPrefixedZero(sb.toString()); if (z.equals("0")) { z = ""; } if (z.length() > 0 && isAbsXLarger) { return "-" + sb.toString(); } else if (z.length() > 0) { return sb.toString(); } else { return "0"; } } /** * 两个正数的加法 * @param x * @param y * @return */ public static String posAddPos(String x, String y) { if (x.length() > y.length()) { String tmp = x; x = y; y = tmp; } x = addZeroToFirst(x, y.length()); String z = ""; int len = x.length(); int[] a = toIntArray(x); int[] b = toIntArray(y); int[] c = new int[len + 1]; int d = 0; for (int i = 0; i < len; i++) { int tmpSum = a[len - 1 - i] + b[len - 1 - i] + d; c[len - i] = tmpSum % 10; d = tmpSum / 10; } c[0] = d; StringBuilder sb = new StringBuilder(); for (int i = 0; i <= len; i++) { sb.append(c[i]); } z = trimPrefixedZero(sb.toString()); return z; } /** * 大整数的乘法 * @param x * @param y * @return */ public static String multi(String x, String y) { if (isNullOrEmpty(x) || isNullOrEmpty(y)) { return null; } if (!isNumeric(x) || !isNumeric(y)) { return null; } if (x.charAt(0) == '-' && y.charAt(0) == '-') { x = x.substring(1); y = y.substring(1); return posMultiPos(x, y); } else if (x.charAt(0) != '-' && y.charAt(0) != '-') { return posMultiPos(x, y); } else if (x.charAt(0) == '-' && y.charAt(0) != '-') { x = x.substring(1); return "-" + posMultiPos(x, y); } else if (x.charAt(0) != '-' && y.charAt(0) == '-') { y = y.substring(1); return "-" + posMultiPos(x, y); } return null; } /** * 一个多位数与一个个位数的乘法,注:这两个数都只能是正数 * @param x * @param y * @return */ private static String posMultiSingleDigit(String x, String y) { if (y.length() != 1 || x.charAt(0) == '-') { throw new IllegalArgumentException("参数异常"); } String z = ""; int len = x.length(); int[] a = toIntArray(x); int b = Integer.parseInt(y); int[] c = new int[len + 1]; int d = 0; for (int i = 0; i < len; i++) { int tempV = a[len - 1 - i] * b; int r = (tempV % 10) + d; d = tempV / 10; if (r >= 10) { c[len - i] = r - 10; d = d + 1; } else { c[len - i] = r; } } c[0] = d; StringBuilder sb = new StringBuilder(); for (int i = 0; i <= len; i++) { sb.append(c[i]); } z = trimPrefixedZero(sb.toString()); return z; } /** * 两个正数的乘法 * @param x * @param y * @return */ public static String posMultiPos(String x, String y) { if (x.length() < y.length()) { String tem = x; x = y; y = tem; } int[] b = toIntArray(y); int len = b.length; String[] temp = new String[len]; for (int i = 0; i < len; i++) { temp[len - 1 - i] = posMultiSingleDigit(x, b[len - 1 - i] + ""); temp[len - 1 - i] += getZeroStringOfLenght(i); } String result = "0"; for (int i = 0; i < len; i++) { result = posAddPos(result, temp[i]); } return result; } /** * 大整数的除法, 如果不能整除, 则小数保留位数为precision,如果能整除,则保留一位小数 * @param x * @param y * @param precision 小数的精度 * @return */ public static String divid(String x, String y, int precision) { if (isNullOrEmpty(x) || isNullOrEmpty(y)) { return null; } if (!isNumeric(x) || !isNumeric(y)) { return null; } boolean flag = false; List<String> li = new ArrayList<String>(); if (x.charAt(0) == '-' && y.charAt(0) == '-') { x = x.substring(1); y = y.substring(1); posDividPos(x, y, "", li, precision, false); } else if (x.charAt(0) != '-' && y.charAt(0) != '-') { posDividPos(x, y, "", li, precision, false); } else if (x.charAt(0) == '-' && y.charAt(0) != '-') { flag = true; x = x.substring(1); posDividPos(x, y, "", li, precision, false); } else if (x.charAt(0) != '-' && y.charAt(0) == '-') { flag = true; y = y.substring(1); posDividPos(x, y, "", li, precision, false); } String result = ""; for(String ele : li) { result += ele; } result = trimPrefixedZero(result); if(flag && !result.equals("0")) { result = "-" + result; } return result; } /** * 两个正整数的除法 * @param x * @param y * @param temp * @param li */ private static void posDividPos(String x, String y, String temp, List<String> li, int precision, boolean dotIncluded) { if (x.length() == 0 && precision == 0) { return; } char[] charArray = x.toCharArray(); String[] xArray = new String[charArray.length]; for (int i = 0; i < charArray.length; i++) { String s = String.valueOf(charArray[i]); xArray[i] = s; } List<String> xList = new ArrayList<String>(Arrays.asList(xArray)); if (xList.size() > 0) { temp += xList.remove(0); } else { if(!dotIncluded) { li.add("."); dotIncluded = true; } if(precision > 0) { precision--; temp += "0"; } } temp = trimPrefixedZero(temp); while (isAbsXLarger(y, temp)) { li.add("0"); if (xList.size() > 0) { temp = temp + xList.remove(0); } else if(precision > 0) { if(!dotIncluded) { li.add("."); dotIncluded = true; } temp = temp + "0"; precision--; temp = trimPrefixedZero(temp); if(temp.equals("0")) { // return; } } else { return; } } int k = cacu(temp, y); li.add(k + ""); String result = add(temp, "-" + posMultiSingleDigit(y, k + "")); result = trimPrefixedZero(result); if (result.equals("0")) { result = ""; } temp = result; String newX = ""; for (String str : xList) { newX += str; } System.out.println(result); posDividPos(newX, y, result, li, precision, dotIncluded); } public static String getZeroStringOfLenght(int a) { String str = ""; for (int i = 0; i < a; i++) { str += "0"; } return str; } public static int[] toIntArray(String str) { int len = str.length(); int[] result = new int[len]; for (int i = 0; i < len; i++) { result[i] = str.charAt(i) - '0'; } return result; } public static String addZeroToFirst(String str, int length) { StringBuilder sb = new StringBuilder(); int diff = length - str.length(); while (diff > 0) { sb.append("0"); diff--; } sb.append(str); return sb.toString(); } public static boolean isNumeric(String str) { Pattern p = Pattern.compile("^\\-?[0-9]*$"); Matcher isNum = p.matcher(str); return isNum.matches(); } public static boolean isNullOrEmpty(String str) { if (str == null) { return true; } if (("").equals(str.trim())) { return true; } return false; } public static boolean isAbsXLarger(String x, String y) { if (x.length() > y.length()) { return true; } else if (x.length() == y.length()) { int[] xArray = toIntArray(x); int[] yArray = toIntArray(y); for (int i = 0; i < xArray.length; i++) { if (xArray[i] > yArray[i]) { return true; } else if (xArray[i] == yArray[i]) { continue; } else { return false; } } } return false; } public static String trimPrefixedZero(String z) { while (z.length() > 1 && z.charAt(0) == '0') { z = z.substring(1); } return z; } /** * 该方法相当于求 x/y的值,注意x、y都是一个正整数 * @param x * @param y * @return */ public static int cacu(String x, String y) { int k = 0; for (int i = 0; i <= 9; i++) { if (isAbsXLarger(x, posMultiSingleDigit(y, i + "")) || (x.equals(posMultiSingleDigit(y, i + "")))) { // System.out.println(x); // System.out.println(posMultiSingleDigit(y, i + "")); k = i; } } return k; } }
相关文章推荐
- 整数大数模拟 高精度加法 高精度减法 高精度乘法 高精度除法 c/c++ java
- 使用main函数的参数,实现一个整数计算器,程序可以接受三个参数,第一个参数“-a”选项执行加法,“-s”选项执行减法,“-m”选项执行乘法,“-d”选项执行除法,后面两个参数为操作数。
- 使用main函数的参数,实现一个整数计算器,程序可以接受三个参数,第一个参数“-a”选项执行加法,“-s”选项执行减法,“-m”选项执行乘法,“-d”选项执行除法,后面两个参数为操作数。
- 使用main函数的参数,实现一个整数计算器,程序可以接受三个参数,第一个参数“-a”选项执行加法,“-s”选项执行减法,“-m”选项执行乘法,“-d”选项执行除法,后面两个参数为操作数。
- 使用main函数的参数,实现一个整数计算器,程序可以接受三个参数,第一个参数“-a”选项执行加法,“-s”选项执行减法,“-m”选项执行乘法,“-d”选项执行除法,后面两个参数为操作数。
- 使用main函数的参数,实现一个整数计算器,程序可以接受三个参数,第一个参数“-a”选项执行加法,“-s”选项执行减法,“-m”选项执行乘法,“-d”选项执行除法,后面两个参数为操作数。
- 使用main函数的参数,实现一个整数计算器,程序可以接受三个参数,第一个参数“-a”选项执行加法,“-s”选项执行减法,“-m”选项执行乘法,“-d”选项执行除法,后面两个参数为操作数。
- 实现一个整数计算器,程序可以接受三个参数,第一个参数“-a”选项执行加法,“-s”选项执行减法,“-m”选项执行乘法,“-d”选项执行除法,后面两个参数为操作数。 例如:输入t
- 使用main函数的参数,实现一个整数计算器,程序可以接受三个参数,第一个参数“-a”选项执行加法,“-s”选项执行减法,“-m”选项执行乘法,“-d”选项执行除法,后面两个参数为操作数。
- 定义一个函数,在该函数中可以实现任意两个整数的加法。java实现
- Java小程序:辗除法求两个正整数最大公约数和最小公倍数
- Java大数模板——加法、减法、乘法、除法、开方、求余
- 不用乘法,除法和mod运算符来分两个整数。 如果溢出,则返回MAX_INT。
- 判断两个有符号整数的加法和乘法是否溢出
- 加法变乘法 如:1+2+3+ ... + 49=1225 现在要求你把其中两个不相邻的加号变成乘号,使得结果为2015,求符合条件的个数(java代码)
- javarscript的加法、乘法、除法不准确的问题
- java实现大整形加法、减法(还没有乘法和除法,目测除法会很难,乘法还凑合)
- 整数高精度运算的库(加法,减法,乘法,除法,取模)
- 用加法实现两个整数乘法操作
- 【Java】只允许使用加号,实现整数的减法,乘法,除法