java大数算法完成五则运算之加减

接昨天的《java大数算法完成五则运算之类基础》这篇文章,今天就先说说加减,毕竟比较简单,就丢一起了。

首先先说说算法思路,就是用最简单的最实用的,我们平时做加减的方法!数字右对齐,往左递推,依次运算,进位借位即可


废话不多说,直接上代码:

关于类中的其它方法和属性详看java大数算法完成五则运算之类基础,这里就不再讲了

public BigNum add(BigNum add) throws Exception {
        int addnum[] = add.NUM;//保存加的数组
        char newNumSign = 0;//保存和的符号
        int newNum[] = null;//保存和的数组
        if (SIGN == add.SIGN) {//同正负号时,符号不变一致
            newNumSign = SIGN;
            newNum = addnum(NUM, addnum);//调用加法
        } else {//异号时,谁的绝对值比较大就用谁的符号
            if (intArrCompaerTo(NUM, addnum) == 1) {
                newNumSign = SIGN;
            } else {
                newNumSign = add.SIGN;
            }
            newNum = subNum(NUM, addnum);//调用减法
        }
        BigNum b = new BigNum(newNum, newNumSign);
        return b;
    }

    private int[] addnum(int a[], int b[]) {
        int p1;//较大大数数组运算指针,指针均从右往左
        int p2;//较小大数数组运算指针
        int num[] = null;//和数组
        int p3;//和数组指针
        if (a.length == b.length) {//当两个大数位数一样时
            p1 = p2 = a.length - 1;
            num = new int[a.length + 1];//加一是因为有可能会多进一位
            p3 = a.length;
            for (; p1 > -1; p1--) {
                int temp = 0;//保存每位之和
                temp = a[p1] + b[p2--];
                if (temp > 9) {//当前位之和大于9要进位
                    num[p3--] = temp % 10;//加上个位
                    num[p3] = temp / 10;//进位
                } else {
                    num[p3--] = temp;
                }
            }
        } else {//两个大数位数不相同时
            int tempNum[] = a;//用临时数组保存当前对象的大数
            if (a.length < b.length) {//tempNum恒存放大的大数,add存放小的大数
                tempNum = b;
                b = a;
            }
            p1 = tempNum.length - 1;
            p2 = b.length - 1;
            num = new int[tempNum.length + 1];
            p3 = tempNum.length;
            for (; p1 > -1; p1--) {
                int temp = 0;//保存每位的和
                if (p2 < 0) {//较小数组可能会先加完
                    temp = tempNum[p1];
                } else {
                    temp = tempNum[p1] + b[p2--];
                }
                if (temp > 9) {//进位
                    num[p3--] = temp % 10;//加上个位
                    num[p3] = temp / 10;//进位
                } else {
                    num[p3--] = temp;
                }
            }
        }
        return num;
    }

加法的代码就是这些,没什么很难的,就是稍微有点绕,要根据符号的不同来选择做加法还是减法,要根据位数不一样来写不同的实现方法,减法也是类似。


接下来是减法:


public BigNum sub(BigNum sub) throws Exception {
        int subNum[] = sub.NUM;//减数
        char newNumSign = 0;//保存差的符号
        int newNum[] = null;//保存差的数组
        if (SIGN == sub.SIGN) {//符号相同时
            switch (compareTo(sub)) {//比较大小
                case -1://小于
                    newNumSign = '-';
                    break;
                case 0://等于
                    newNumSign = '+';
                    newNum = new int[1];
                    newNum[0] = 0;
                    break;
                case 1://大于
                    newNumSign = '+';
                    break;
            }
            newNum = subNum(NUM, sub.NUM);//调用减法
        } else {//异号
            if (SIGN == '+') {
                newNumSign = '+';
            } else {
                newNumSign = '-';
            }
            newNum = addnum(NUM, sub.NUM);//调用加法
        }
        BigNum b = new BigNum(newNum, newNumSign);
        return b;
    }

    private int[] subNum(int a[], int b[]) {
        int p1 = 0;//较大大数数组运算指针,指针均从右往左
        int p2 = 0;//较小大数数组运算指针
        int num[] = null;//余数组
        int big[] = a;//保存较大数组,b保存较小数组
        int p3 = 0;//余数组指针

        switch (intArrCompaerTo(a, b)) {//比较两个数组大小,使得big恒保存较大数组
            case -1://a小于b
                big = b;
                b = a;
                p1 = big.length - 1;
                p2 = b.length - 1;
                num = new int[big.length];
                p3 = num.length - 1;
                break;
            case 0://a=b,结果为零,直接返回
                num = new int[1];
                num[0] = 0;
                return num;
            case 1://a大于b
                p1 = big.length - 1;
                p2 = b.length - 1;
                num = new int[big.length];
                p3 = num.length - 1;
                break;
        }
        for (; p1 > -1; p1--) {//以大数组的长度来从右往左运算
            if (p2 < 0) {//当大数组还有数字而小数组没有后执行
                if (big[p1] < 0) {//如果当前位小于0,即在上一次循环中被借了一位,再往前借一次
                    big[p1 - 1] -= 1;
                    big[p1] += 10;
                }
                num[p3--] = big[p1];
            } else {//小数组还有数字
                if (big[p1] < b[p2]) {//大数组的当前位小于小数组的当前位时借位
                    big[p1 - 1] -= 1;
                    big[p1] += 10;
                }
                num[p3--] = big[p1] - b[p2--];
            }
        }
        return num;
    }


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值