Java 大数、高精度模板

介绍:

  java中用于操作大数的类主要有两个,一个是BigInteger,代表大整数类用于对大整数进行操作,另一个是BigDecimal,代表高精度类,用于对比较大或精度比较高的浮点型数据进行操作。因为这两种类的使用方法是一样的,所以下面我们以BigInteger为例进行讲解

基本用法:

  

1、新建一个值为123的大整数对象 
BigInteger a=new BigInteger(“123”); //第一种,参数是字符串 
BigInteger a=BigInteger.valueOf(123); //第二种,参数可以是int、long

// BigInteger a = BigInteger( string x);

2、大整数的四则运算 
a. add(b); //a,b均为BigInteger类型,加法 ,这里并没有在a上加上b,而是返回了一个a+b的对象

a.subtract(b); //减 法 
a.divide(b); //除法 
a.multiply(b); //乘法

3、大整数比较大小 
a.equals(b); //如果a、b相等返回true否则返回false 
a.comareTo(); //a小于b返回-1,等于返回0,大于返回1

4、常用方法 
a.mod(b); //求余 
a.gcd(b); //求最大公约数 
a.max(b); //求最大值 
a.min(b); //求最小值

5、BigInteger中的常数 
BigInteger.ZERO //大整数0 
BigInteger.ONE //大整数1 
BigInteger.TEN //大整数10

输入模板:

1     Scanner cin = new Scanner(System.in); //读入
2     while(cin.hasNext()){  //等同于!=EOF
3         BigInteger a;
4         a = cin.BigInteger();   //读入一个BigInteger;
5         System.out.println(a);   //输出a并换行
6     }

劳动成果窃取~

 1 //d为int型,a,b,c都为大数
 2 c=a.add(b);             //  相加
 3 c=a.subtract(b);       //    相减
 4 c=a.multiply(b);          // 相乘
 5 c=a.divide(b);        // 相除取整
 6 c=a.gcd(b);          //  最大公约数
 7 c=a.remainder(b);   //  取余
 8 c=a.mod(b);         // a mod b
 9 c=a.abs();           // a的绝对值
10 c=a.negate();        // a的相反数
11 c=a.pow(d);           // a的b次幂        d为int型    
12 c=a.max(b);           //  取a,b中较大的
13 c=a.min(b);                //  取a,b中较小的
14 d=a.compareTo(b);    //比较a与b的大小 d=-1小于d=0等于 d=1大于  d为int型
15 a.equals(b);       //  判断a与b是否相等    相等返回true  不相等返回false  
16 d=a.intValue();      //       将大数a转换为 int 类型赋值给 d  
17 e=a.longValue();     //       将大数a转换为  long 类型赋值给 e  
18 f=a.floatValue();    //       将大数a转换为  float 类型赋值给 f  
19 g=a.doubleValue();   //       将大数a转换为  double 类型赋值给 g  
20 s=a.toString();      //     将大数a转换为 String 类型赋值给 s  
21 <span style="color:#ff0000;">s=a.toPlainString();  //将大数a转换为String类型赋值给s,且不表示为科学计数法</span>  
22 a=BigInteger.valueOf(e);  // 将 e 以大数形式赋值给大数 a   e只能为long或int  
23 a=newBigInteger(s, d);  // 将s数字字符串以d进制赋值给大数a如果d=s字符数字的进制则等同于将数字字符串以大数形式赋值给大数a  
24 String st = Integer.toString(num, base); //把int型num当10进制的数转成base进制数存入st中    (base <= 35).  
25 int num = Integer.parseInt(st, base); //把st当做base进制,转成10进制的int  
26 (parseInt有两个参数,第一个为要转的字符串,第二个为说明是什么进制).    
27 BigInter m = new BigInteger(st, base); // st是字符串,base是st的进制.  
28 BigInteger a;  
29 int b;  
30 Stringc;  
31 a=cin.nextBigInteger(b);   //以b进制读入一个大数赋值给a  
32 c=a.toString(b);          // 将大数a以b进制的方式赋给字符串c  
33 a=newBigInteger(c, b);  //把c 当做“b进制“转为十进制大数赋值给a  

 

 

注意:

使用java大数类解决问题时我们需要注意两个方面 :
1、不能有包名,也就是说我们要把主类放到默认的包里,如果你的代码里出现形如package cn.gov.test;这样的代码你很有可能会收获到RE 
2、提交的类的类名必须为Main,如果是其他的名字你有可能收获到CE也有可能收获到WA(例如UVA)

光说不练假把式,学习了理论之后我们更需要编码练习,下面是我挑选的几个例题,希望能帮助到你

1:判断a == b
题目描述:输入两个非常大的数A和B,判断A是否等于B,如果相等输出YES,否则输出NO 
分析:这个题在hdu上实际上并没有给出范围,WA了之后才知道这是道大数题,因为仅仅涉及到输入、比较和输出,所以非常适合用作大数的入门题 
注意:这里只是说给出两个数A和B,并没有说是两个整数,所以应该采用BigDecimal 

 1 import java.math.BigDecimal;
 2 import java.util.Scanner;
 3 
 4 public class Main {
 5 
 6     public static void main(String[] args) {
 7         // TODO Auto-generated method stub
 8 
 9         BigDecimal a, b;
10         Scanner cin = new Scanner(System.in);
11 
12         while (cin.hasNext()) {
13             a = cin.nextBigDecimal();
14             b = cin.nextBigDecimal();
15             if (a.compareTo(b) == 0) System.out.println("YES");
16             else System.out.println("NO");
17         }
18 
19     }
20 
21 }

2、大整数加法
题目描述:求两个不超过200位的非负整数的和。 
分析:也是非常简单的入门题,直接输入后调用BigInteger自带的方法add即可 

 1 import java.math.BigInteger;
 2 import java.util.Scanner;
 3 
 4 public class Main {
 5 
 6     public static void main(String[] args) {
 7         // TODO Auto-generated method stub
 8 
 9         BigInteger a,b;
10 
11         Scanner cin = new Scanner(System.in);
12 
13         a = cin.nextBigInteger();
14         b = cin.nextBigInteger();
15 
16         System.out.println(a.add(b));
17     }
18 
19 }

3、大数阶乘
题目描述:给你一个n,计算n的阶乘,但是n很可能比较大 
分析:学会java大数后这就是一道不折不扣的水题,新手找找AC的快感吧 

 1 import java.math.BigInteger;
 2 import java.util.Scanner;
 3 
 4 public class Main {
 5 
 6     public static BigInteger getTac(BigInteger a)
 7     {
 8         if(a.compareTo(new BigInteger("1")) <= 0)
 9             return new BigInteger("1");
10         else
11             return a.multiply(getTac(a.subtract(new BigInteger("1"))));
12     }
13 
14     public static void main(String[] args) {
15         // TODO Auto-generated method stub
16         Scanner cin = new Scanner(System.in);
17         BigInteger m;
18         while(cin.hasNext())
19         {
20             m = cin.nextBigInteger();
21             m = getTac(m);
22             System.out.println(m);
23         }
24 
25     }
26 
27 }        

4、大斐波数
题目描述:计算第n项Fibonacci数值,n可能比较大 
分析:这个题与之前的两个水题相比有了一定的含金量,直接按定义求解是会收获TLE的,所以我们需要用递推加打表

 1 import java.math.BigInteger;
 2 import java.util.Scanner;
 3 
 4 
 5 public class Main {
 6 
 7     public static void main(String[] args) {
 8         // TODO Auto-generated method stub
 9         Scanner cin = new Scanner(System.in);
10 
11         BigInteger[] nums = new BigInteger[1010];
12         nums[1] = new BigInteger("1");
13         nums[2] = new BigInteger("1");
14         for(int i = 3; i <= 1000; i++)
15             nums[i] = nums[i - 1].add(nums[i - 2]);
16 
17         int T = cin.nextInt();
18         while(T > 0)
19         {
20             T--;
21             int n = cin.nextInt();
22             System.out.println(nums[n]);
23         }
24 
25     }
26 
27 }

5、A/B
题目描述:要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。 
分析:最容易想到的方法莫过于让n一直加9973加到n Mod b == 0,不过很可惜这样做会超时的;所以我们换一种思路,因为a一定能被b整除,所以a一定是b的倍数,于是我们让a = b * i(i= 1,2,3···)直到a Mod b == n;此时得到大整数a直接用题目中给的公式就能将正确答案做出来

 1 import java.math.BigInteger;
 2 import java.util.Scanner;
 3 
 4 public class Main {
 5 
 6     public static void main(String[] args) {
 7         // TODO Auto-generated method stub
 8 
 9         Scanner cin = new Scanner(System.in);
10         int T = cin.nextInt();
11         while(T > 0)
12         {
13             T--;
14             BigInteger a = cin.nextBigInteger();
15             BigInteger b = cin.nextBigInteger();
16             BigInteger d = new BigInteger("9973");
17             BigInteger z = new BigInteger("0");
18 
19 
20             for(BigInteger i = new BigInteger("1"); ; i = i.add(new BigInteger("1")))
21             {
22                 BigInteger c = b.multiply(i);
23                 if(c.mod(d).compareTo(a) == 0)
24                 {
25                     System.out.println(i.mod(d));
26                     break;
27                 }
28             }
29         }
30 
31     }
32 
33 }

 

高精度类的使用:

 1  String temp1 = "1.2222222222222222222222222";
 2             BigDecimal bd1 = new BigDecimal(temp1);
 3             String temp2 = "2.333333333333333333333333";
 4             BigDecimal bd2 = new BigDecimal(temp2);
 5             System.out.println(bd1.add(bd2));                       // 加法  输出   3.5555555555555555555555552
 6             System.out.println(bd1.add(bd2).doubleValue());         // 输出    3.5555555555555554 这里用了一个方法将结果转化为double类型了
 7 
 8             System.out.println(bd2.subtract(bd1));                  //减法    输出 1.1111111111111111111111108
 9             System.out.println(bd2.subtract(bd1).doubleValue());    //输出   1.1111111111111112
10 
11             System.out.println(bd2.multiply(bd1));                  //乘法 输出    2.8518518518518518518518513925925925925925925925926
12             System.out.println(bd2.multiply(bd1).doubleValue());    //乘法    2.8518518518518516
13 
14             System.out.println(bd2.divide(bd1, 5, RoundingMode.HALF_UP));                    //除法应该注意很有可能会有除不尽的情况,这时候会有异常抛出,所以要传入控制参数
15             System.out.println(bd2.divide(bd1, 5, RoundingMode.HALF_UP).doubleValue());     //输出都是  1.90909
16 
17             System.out.println(bd1.compareTo(bd2));                 //比较方法
18             BigDecimal bd3 = new BigDecimal("1.20");
19             BigDecimal bd4 = new BigDecimal("1.2");
20             System.out.println(bd3.compareTo(bd4));           //返回0表示相等
21             System.out.println(bd3.equals(bd4));             //返回的是false  是错误的
22                                                              //所以比较的时候使用compareTo()方法

 

posted @ 2018-09-19 18:50  会打架的程序员不是好客服  阅读(722)  评论(0编辑  收藏  举报