提到大数运算,JAVA绝对赖皮,不像C,JAVA自带大整数(java.math.BigInteger)的库。这方面也是了解了一下,关于大整数,这一篇文章还是讲的很全面的:(6条消息) Java 大数字运算_Darklovy-

题目大概效果就是这样:

import java.math.BigInteger;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        String  a;
        Scanner scanner=new Scanner(System.in);
        a=scanner.nextLine();
        BigInteger m=new BigInteger(a);
        for (int i=2;i<10;i++){
            BigInteger n=BigInteger.valueOf(i);
            BigInteger result[]=m.divideAndRemainder(n);
            int num=result[1].intValue();
            if(num==0){
                System.out.print(i+" ");
            }
        }
    }
}

肯定是比纯数组的方法简单的多,有了自带的库无脑往上码就是了。


那么,如果没有这个库,用数组应该怎么做呢。

1.首先,将大数的每一位装进数组。比较通用的方法就是做一个循环一直mod10来求余数。

不过,大数是不能用int来初始化的,我们得到的是一个字符串类型的大数,mod10显然行不通。

于是想到String的toCharArray():

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        String  a;
        Scanner input=new Scanner(System.in);
        a=input.nextLine();
        char[] c=a.toCharArray();
        int[] d=new int[100];
        for (int i=0;i<c.length;i++){
            d[99-i]=(int)c[i]-48;
        }
        for (int i=0;i<100;i++){
            System.out.print(d[i]);
        }
    }
}

运行的结果和预期一样。这段代码是我第一时间想到的,当然肯定会有更简洁的代码是可行的,仅做参考。值得注意的是,当我们强制int 类型为char的函数,我们得到的是它的ASCII码,而由于数组的每一个元素都是个位数,所以只要减去48就是我们想要的数字。

然后在循环的时候顺带做个逆序排列,得到的结果:

java 用什么类型存大数 java中大数_后端

 接下来加减法就很简单了:

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        String  a,b;
        Scanner input=new Scanner(System.in);
        a=input.nextLine();
        b=input.nextLine();
        char[] c=a.toCharArray();
        char[] e=b.toCharArray();
        int[] d=new int[100];
        int[] f=new int[100];
        int[] res=new int[100];
        for (int i=0;i<c.length;i++){
            d[i+100-c.length]=(int)c[i]-48;
        }
        for (int i=0;i<e.length;i++){
            f[i+100-c.length]=(int)e[i]-48;
        }
        for(int i=0;i<100;i++){
            res[i]=d[i]-f[i];
            if(res[i]<0){
                res[i]+=10;
                d[i+1]-=1;
            }
        }
        boolean flag=false;
        for (int i=0;i<100;i++){
            if(res[i]!=0)flag=true;
            if(flag)System.out.print(res[i]);
        }
    }
}

为了表达清楚,有些循环并没有合并,事实上用不到那么多for循环。这里是以减法为例子,答案也是正确的:

java 用什么类型存大数 java中大数_java 用什么类型存大数_02


 加减法是互通的,而难点就在于乘除。

乘除算法略比加减法复杂,先说乘法:

乘法可以想象我们的笔算

java 用什么类型存大数 java中大数_java 用什么类型存大数_03

 很容易想到用二维数组,再利用for循环每次错一位相加。但由于大数相乘除比较复杂,使用数组的性价比实在太低,不如好好掌握大数的库进行运算。因此,我们碰到的很多题目都是大数乘以小数。当然,当一个大数乘以一个个位数就简单多了,只要在对res[I]的计算做一些小改动即可,你也可以将加法循环n次;


那么,除法应该怎么做呢?显然,除法是这里最困难的一种算法,因为需要考虑到有余数的情况,这里就写了大整数除以个位数的情况:

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        String  a;
        Scanner input=new Scanner(System.in);
        a=input.nextLine();
        double b=input.nextDouble();
        char[] c=a.toCharArray();
        int[] d=new int[100];
        int[] res=new int[100];
        for (int i=0;i<c.length;i++){
            d[i+100-c.length]=(int)c[i]-48;
        }
        int yu=0;
        for(int i=0;i<d.length-1;i++){
            double m=d[i];double n=d[i+1];
            res[i]=(int)Math.floor((m*10+n)/b);
            yu=(int)((m*10+n)%b);
            d[i+1]=yu;
        }
        System.out.println(yu);
        boolean flag=false;
        for (int i=0;i<99;i++){
            if(res[i]!=0)flag=true;
            if(flag)System.out.print(res[i]);
        }
    }
}

虽然比加减法复杂,但应该还是很好想到的。这是我第一时间想到的代码,日后还会完善改良。

计算结果也是正确的:

java 用什么类型存大数 java中大数_i++_04

第一行输出余数,第二行输出商。 

总的来说JAVA在写大数的时候还是选择加入BigInteger比较好,今天也是在CSDN上没有找到数组方法的大数运算,于是顺便写了一篇。

学JAVA刚一个月,有不足之处还请大佬指出。