两个大整数的模拟加法

一、主要目的

模拟实现两个很大的数之间进行加法;


二、主要思路

1、把两个数当做字符串存放到内存里;
2、从后面开始遍历这两个字符串;
3、把对应位置的字符,转成单个整数,然后相加,判断是否出现进位;
4、没有进位就直接保存在结果里;有进位需要处理进位;


三、代码如下

(一)相加类

/**
 * 模拟相加和移位运算
 */
public class CPU {

    /**
     * 模拟十进制整数之间的加法
     * 每一位相加,进行进位;
     *
     *
     * @param left
     * @param right
     */
    public static void add(String left, String right){
        if (left != null && right != null) {
            if (isCorrect(left) && isCorrect(right)) {

                // 首先向右对齐才能计算
                // 如果两个数字位数不相等,就进行填充数字0进行相等;
                if (left.length() != right.length()) {
                  if (left.length() > right.length()) {
                      StringBuffer buffer = new StringBuffer(right);
                      buffer.insert(0, getZeros(left.length() - right.length()));
                      right = buffer.toString();
                  } else {
                      StringBuffer buffer = new StringBuffer(left);
                      buffer.insert(0, getZeros(right.length() - left.length()));
                      left = buffer.toString();
                  }
                }
                System.out.println("left:" + left.toString());
                System.out.println("right:" + right.toString());

                // 定义存放结果的缓冲(填充相同位数的0)
                StringBuffer result = new StringBuffer(getZeros(left.length()));

                int v1,v2,v3;
                int temp = 0;
                // 从右边开始,遍历两个字符串的每一位字符
                for (int k = left.length() - 1; k >= 0; k--) {
                    // 获得字符的数字代表的整数,例如ASCII字符'1'的字节值减去48后等于1
                    v1 = left.charAt(k) - 48;
                    v2 = right.charAt(k) - 48;
                    v3 = result.charAt(k) - 48;

                    // 计算某一位的相加值
                    temp = v1 + v2 + v3;

                    // 如果大于9,需要往高位进1
                    if (temp > 9) {
                        result.setCharAt(k, (char)((temp % 10) + 48));
                        // 把进位1设置在result字符串里
                        carry(result, left.length() - k + 1);
                    } else {
                        result.setCharAt(k, (char)(temp + 48));
                    }
                }

                System.out.println("加法计算结果为:" + result.toString());
            } else {
                throw new IllegalArgumentException("not digit calculation.");
            }
        }
    }

    /**
     * 处理字符的进位
     *    进位规则:
     *       从右边依次将每一位进行计算,转成数字后,相加后的结果,如果超过10就进1;
     *       例如:5 + 6 = 11 ,那么向前加一,当前位是1;
     *       需要把这进位的1,加到前面;
     * @param result 目标结果的字符
     * @param index 需要加一的位置;从右侧开始编号,第一位是1;
     */
    public static void carry(StringBuffer result, int index) {
        // 1、如果位数不够,需要在前面填充0
        if (result.length() < index){
            result.insert(0, '0');
        }

        // 2、获得需要进位的数字的整型值
        int digit = result.charAt(result.length() - index) - 48;

        // 3、数字加一
        digit = digit + 1;

        // 4、如果超过9,需要给前面的数字进一
        if (digit > 9){
            // 4.1、获得余数
            int leaving = digit % 10;

            // 4.2、给当前位设置为余数
            result.setCharAt(result.length() - index, (char)(leaving + 48));

            // 4.3、给前面的位数加一
            carry(result, index + 1);
        } else {
            // 5、直接设置当前位
            result.setCharAt(result.length() - index, (char)(digit + 48));
        }
    }

    /**
     * 返回想要的数字0组成的字符串
     * @param num 个数
     * @return 字符串
     */
    public static String getZeros(int num){
        StringBuffer result = new StringBuffer();
        for (int k = 1; k <= num; k++) {
            result.append("0");
        }
        return result.toString();
    }

    /**
     * 判断数字是否正确
     * @param digit
     * @return
     */
    public static boolean isCorrect(String digit){
        boolean isCorrect = true;

        if (digit != null && digit != "") {
            char t = ' ';
            // 如果出现一个字符不是数字,就返回不正确
            for (int i = 0; i < digit.length(); i++) {
                t = digit.charAt(i);
                if (t < '0' || t > '9'){
                    isCorrect = false;
                    break;
                }
            }
        } else {
            isCorrect = false;
        }

        return isCorrect;
    }
}

(二)测试类

public class Test{

    public static void main(String[] args) {
            System.out.println("模拟加法:");
            CPU.add("655555555555555566666884422214555545555120", "434353535353553534280");
    }
    
}

四、测试结果如下

在这里插入图片描述


五、总结

1、大数相加已经超出long类型变量的存储范围。

2、需要用字符串来存储,甚至使用磁盘文件来存放位数很大的整数或者小数;

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值