前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >高精度运算

高精度运算

作者头像
每天学Java
发布2020-06-01 10:51:05
1.3K0
发布2020-06-01 10:51:05
举报
文章被收录于专栏:每天学Java每天学Java

向英雄致敬,向逝者致哀 愿逝者安息,生者奋发 愿国泰民安,山河无恙

前言

在写Java代码时候,我们其实很少去考虑高精度运算,即使遇到无法避免高精度的计算问题也不会太烦恼,因为有大整数类BigInteger以及BigDecimal工具使用。

但是抛开Java不说,像自己之前在为一家银行计算员工工资的时候,自己还是使用JS去处理计算然后做页面展示的,但是因为银行系统 引入包是比较费劲的,所以当时自己第一次将高精度运算运用到工作中,之后由于使用Java越来越多,对于手撸高精度计算代码也就越来越少了。但是直到过年在家使用C++刷PAT算法的时候,又不可避免的使用到高精度算法(因为long int和long long也无法解决整数长度受限的问题), 所以今天得空用Java来实现高精度的运算(嗯.....有没有意义不知道,反正闲着也是闲着),除法就先放一放,因为高精度除高精度有点难,这里就谈一谈高精度的加减乘。先看一下效果图(上方结果使用BigInteger的方法,下方结果自定义实现)

正文

高精度加

高精度的加法是比较容易理解的和实现,我们只需要注意进位就好, 将输入整数的字符串,进行遍历,将char类型转为int进行相加,保存进位在下一轮循环中使用即可。

代码语言:javascript
复制
    private static void add(String a, String b) {
        System.out.println("加===");
        BigInteger ba = new BigInteger(a);
        BigInteger bb = new BigInteger(b);
        System.out.println("结果=" + ba.add(bb));
        String res = "";
        int temp;
        int adv = 0;
        for (int i = a.length() - 1, j = b.length() - 1; i > -1 || j > -1; ) {
            if (i > -1 && j > -1)
                temp = (a.charAt(i--) - '0') + (b.charAt(j--) - '0');
            else if (i > -1)
                temp = (a.charAt(i--) - '0');
            else
                temp = (b.charAt(j--) - '0');
            temp += adv;
            adv = temp / 10;
            res = temp % 10 + res;
        }
        if (adv != 0) {
            res = adv + res;
        }
        System.out.println("结果=" + res);
    }

高精度减法

高精度减法和加法比较,稍微复杂一些,因为在减法中,需要根据输入数字的相对大小来判断是否输出负号,还需要注意是否要"借位",以及对于结果进行高位去0

代码语言:javascript
复制
    private static void sub(String a, String b) {
        System.out.println("减===");
        BigInteger ba = new BigInteger(a);
        BigInteger bb = new BigInteger(b);
        System.out.println("结果=" + ba.subtract(bb));
        String res = "";
        int temp;
        int sub = 0;
        String ch = "";
        if (a.length() < b.length() || (a.compareTo(b) < 0)) {//正数
            String c = a;
            a = b;
            b = c;
            ch = "-";
        }
        for (int i = a.length() - 1, j = b.length() - 1; i > -1 || j > -1; ) {
            if (i > -1 && j > -1) {
                int tempA = a.charAt(i--) - '0' + sub;
                sub = 0;
                int tempB = b.charAt(j--) - '0';
                if (tempA < tempB) {
                    sub = -1;
                    temp = tempA + 10 - tempB;
                } else {
                    temp = tempA - tempB;
                }
            } else if (i > -1) {
                temp = (a.charAt(i--) - '0') + sub;
                sub = 0;
            } else {
                temp = (b.charAt(j--) - '0') + sub;
                sub = 0;
            }

            res = temp + res;
        }
        //高位去0
        int spilt = 0;
        for (int i = 0; i < res.length(); i++) {
            if (res.charAt(i) - '0' != 0) {
                break;
            } else {
                spilt++;
            }
        }
        res = res.substring(spilt);
        System.out.println("结果=" + ch + res);
    }

高精度乘法

乘法和加法类似,但是因为涉及到累计相加的过程(模拟算术做竖式乘法的过程),所以结合数组更加方便理解一些

代码语言:javascript
复制
    private static void multiply(String a, String b) {
        System.out.println("乘法===");
        BigInteger ba = new BigInteger(a);
        BigInteger bb = new BigInteger(b);
        System.out.println("结果=" + ba.multiply(bb));
        int as[] = new int[a.length()];
        int bs[] = new int[b.length()];
        for (int i = 0; i < a.length(); i++) {
            as[i] = a.charAt(a.length() - i - 1) - '0';
        }

        for (int i = 0; i < b.length(); i++) {
            bs[i] = b.charAt(b.length() - i - 1) - '0';
        }
        int res[] = new int[b.length() + a.length()];

        for (int i = 0; i < a.length(); i++) {
            int adv = 0;
            int j;
            for (j = 0; j < b.length(); j++) {
                res[i + j] = as[i] * bs[j] + adv + res[i + j];
                adv = res[i + j] / 10;
                res[i + j] = res[i + j] % 10;
            }
            res[i + j] = adv;
        }
        int len = a.length() + b.length() - 1;
        if (res[len] == 0) len--;
        System.out.printf("结果=");
        for (int i = len; i >= 0; i--) {
            System.out.printf(res[i] + "");
        }
    }

主函数:

代码语言:javascript
复制
public class Test {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入a");
        String a = "";
        if (scanner.hasNext())
            a = scanner.next();
        System.out.println("输入b");
        String b = "";
        if (scanner.hasNext())
            b = scanner.next();
        add(a, b);
        sub(a, b);
        multiply(a, b);
    }

}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 每天学Java 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 正文
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档