package top.chitucao.algorithm.Math;

import java.util.Objects;

/**
 * @author chitucao
 * @since 2022/11/23 10:10
 * 大数加法,包括正负的情况
 * 参考 https://developer.aliyun.com/article/1057265
 */
public class LargeNumber {

    public static void main(String[] args) {
        String num1 = "123";
        String num2 = "-456";
        System.out.println(new LargeNumber().add(num1, num2));
    }

    public String add(String num1, String num2) {

        boolean isPositiveNum1 = num1.charAt(0) != '-';
        boolean isPositiveNum2 = num2.charAt(0) != '-';

        if (isPositiveNum1 && isPositiveNum2) {
            return doAdd(num1, num2);
        } else if (!isPositiveNum1 && !isPositiveNum2) {
            return negate(doAdd(num1.substring(1), num2.substring(1)));
        } else if (isPositiveNum1 && !isPositiveNum2) {
            return doSub(num1, num2.substring(1));
        } else {
            return doSub(num2, num1.substring(1));
        }
    }

    // 相加
    private String doAdd(String num1, String num2) {
        int len1 = num1.length() - 1;
        int len2 = num2.length() - 1;
        int carry = 0;

        StringBuilder sb = new StringBuilder();

        while (len1 >= 0 || len2 >= 0) {
            int n1 = len1 >= 0 ? num1.charAt(len1--) - '0' : 0;
            int n2 = len2 >= 0 ? num2.charAt(len2--) - '0' : 0;
            int sum = n1 + n2 + carry;
            carry = sum / 10;
            sb.append(sum % 10);
        }

        // 这里注意进位
        if (carry > 0) {
            sb.append(1);
        }

        return sb.reverse().toString();
    }

    // 相减
    private String doSub(String num1, String num2) {
        if (!compare(num1, num2)) {
            return negate(doSub(num2, num1));   // 保证num1>=num2
        }

        int len1 = num1.length() - 1;
        int len2 = num2.length() - 1;
        int borrow = 0;

        StringBuilder sb = new StringBuilder();

        while (len1 >= 0 || len2 >= 0) {
            int n1 = len1 >= 0 ? num1.charAt(len1--) - '0' : 0;
            int n2 = len2 >= 0 ? num2.charAt(len2--) - '0' : 0;
            int num = n1 - n2 - borrow;

            // 借位
            if (num < 0) {
                borrow = 1;
                num += 10;
            }
            sb.append(num);
        }

        // 反转后去掉前导0  22-14=08
        sb.reverse();
        int idx = 0;
        while (idx < sb.length() && sb.charAt(idx) == '0') {
            idx++;
        }
        // 等于0的特殊情况
        if (idx == sb.length()) {
            return "0";
        }

        return sb.substring(idx);
    }

    // num1是否大于等于num2
    private boolean compare(String num1, String num2) {
        if (num1.length() == num2.length()) {
//            return num1.compareTo(num2) >= 0;
            for (int i = 0; i < num1.length(); i++) {
                if (num1.charAt(i) < num2.charAt(i)) {
                    return false;
                }
            }
            return true;
        } else {
            return num1.length() > num2.length();
        }
    }

    // 反转正负情况
    private String negate(String num) {
        if (num.charAt(0) == '-') {
            return num.substring(1);
        } else if (Objects.equals(num, "0")) {
            return num;
        } else {
            return "-" + num;
        }
    }

}

  

原文地址:http://www.cnblogs.com/chitucao/p/16917964.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性