Java模拟两个大整数的加法、乘法、除法

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;

    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值