Java 大数乘法

问题

大数乘法
对于32位字长的机器,大约超过20亿,用int类型就无法表示了,我们可以选择int64类型,但无论怎样扩展,固定的整数类型总是有表达的极限
如果对超级大整数进行精确运算呢?一个简单的办法是:仅仅使用现有类型,但是把大整数的运算化解为若干小整数的运算,即所谓:“分块法”
每一个数可以分成两个或以上的数相乘,最终对结果进行累加
x2 x1
X y2 y1
/ -----------
m1 m1 ->( y1 * x1)
m2 m2 ->( y1 * x2)
m3 m3 ->( y2 * x2 )
m4 m4 ->( y2 * x2)
/-------------
r0 r1 r2 r3

上图表示了分块乘法的原理。可以把大数分成多段(此处为2段)小数,然后用小数的多次运算组合表示一个大数
可以根据int的承载能力规定小块的大小,比如要把int分成2段,则小块可取10000为上限值。注意,小块在进行纵向累加后,需要进行进位校正

解题

    /**
     * 大数乘法
     * 对于32位字长的机器,大约超过20亿,用int类型就无法表示了,我们可以选择int64类型,但无论怎样扩展,固定的整数类型总是有表达的极限
     * 如果对超级大整数进行精确运算呢?一个简单的办法是:仅仅使用现有类型,但是把大整数的运算化解为若干小整数的运算,即所谓:“分块法”
     * 每一个数可以分成两个或以上的数相乘,最终对结果进行累加
     *       x2  x1
     *    X  y2  y1
     * -----------
     *       m1  m1  ->( y1 * x1)
     *    m2 m2      ->( y1 * x2)
     *    m3 m3      ->( y2 * x2 )
     * m4 m4         ->( y2 * x2)
     *-------------
     * r0 r1 r2 r3
     *
     * 上图表示了分块乘法的原理。可以把大数分成多段(此处为2段)小数,然后用小数的多次运算组合表示一个大数
     * 可以根据int的承载能力规定小块的大小,比如要把int分成2段,则小块可取10000为上限值。注意,小块在进行纵向累加后,需要进行进位校正
     *
     */
    public static void BigNumberMul(int bigNumber1, int bigNumber2, int r[]){
        // 标准1
        int base = 10000;

        // 对大数进行拆分 最终拆分结果还是等于两数之积
        int x2 = bigNumber1 / base;
        int x1 = bigNumber1 % base;
        int y2 = bigNumber2 / base;
        int y1 = bigNumber2 % base;

        // 拆分后中间结果
        int sum1 = y1 * x1;
        int sum2 = y2 * x1;
        int sum3 = y1 * x2;
        int sum4 = y2 * x2;

        r[3] = sum1 % base;
        r[2] = sum1 / base + sum2 % base + sum3 % base;
        r[1] = sum2 / base + sum3 / base + sum4 % base;
        r[0] = sum4 / base;

        r[1] += r[2] / base;
        r[2] = r[2] % base;
        r[0] += r[1] / base;
        r[1] = r[1] % base;

        StringBuilder stringBuilder = new StringBuilder();
        if (r[0] == 0){
            System.out.println(stringBuilder.append(r[1]).append(r[0]).append(r[2]).append(r[3]));
        } else {
            System.out.println(stringBuilder.append(r[0]).append(r[1]).append(r[2]).append(r[3]));
        }

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值