Java BigInteger 和 BigDecimal 在 ACM 中的应用

开头

首先,有几点需要注意的

名词大致对应关系(Java —> C的对应关系,单纯针对没学过C++的同学,学过C++可无视)

  • 方法 —> 函数
  • 成员变量 —> 变量
  • 一个xxx对象 —> 一个xxx结构体变量 + 处理这个变量的函数集合
  • xxx的成员函数 —> 可以对xxx结构体内的变量进行操作的一类函数
    在 ACM 中提交 Java 的类名必须是 Main,且不包含包名.

一般来说 Java 提交的代码格式都是这样

1
2
3
4
5
6
7
8
9
//常用的工具类,包括输入等
import java.util.*;

import java.math.*;
public class Main {
public static void main(String[] args) {
//blablabla...
}
}

而大数处理就需要用到 java.math 中的 BigInteger类 和BigDecimal类. 其中,BigInteger用于处理大整数, BigDecimal 用于处理浮点数

在 Java 中,你完全可以使用 C/C++ 的语法,但是要注意一点: bool类型在 Java 中是Boolean,而且不能用0,1一类的数值赋值,只能用 true/false.如下:

1
2
3
4
5
public class Main {
public static void main(String[] args) {
Boolean flag = false;
}
}

对于基本型变量(int,char,byte,float一类),在 Java 中是值传递的(对比 C/C++中的 = 号).但是对于对象却是用的引用传递(类似指针的一个东西)

也就是说在对象中,对于对象的赋值最好不直接用 = 进行赋值,而是用自己写的方法(如BigInteger中的13-15行)进行赋值.因为在某个版本的库中如果返回的不是一个 new 的对象的话就相当于 C/C++ 中2个指针指向了同一处地址

通用

比较

BigIntegerBigDecimal的数值比较都需要用到 compareTo 方法.需要注意的是,该方法返回的是 int 类型.也就是说不能用if(a.compareTo(b))的形式.(前面讲过int不能用于对Boolean赋值,所以不能将其隐式转换为Boolean)

通常,我们都用以下语句进行判断

1
if(x.compareTo(y) <op> 0)//其中 <op> 是六个比较运算符之一,如 >, <, =。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.math.BigDecimal;

public class Main {
public static void main(String[] args) {
BigDecimal a = new BigDecimal("1.1111111112");
BigDecimal b = new BigDecimal("1.1111111111");
if(a.compareTo(b) > 0){
System.out.println("a > b");
}
else if (a.compareTo(b) == 0){
System.out.println("a==b");
}
else {
System.out.println("a < b");
}
}
}

BigInteger

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/**
* @ClassName @{Name}
* @Description BigInteger的简单使用
* @Author bestsort
* @Date 19-8-10 上午8:11
* @Version 1.0
*/

import java.math.*;
import java.util.*;


public class Main {
public static BigInteger get(BigInteger num){
return num;
}
public static void main(String[] args) {
//单个大数,记得初始化为null
BigInteger a = null;
BigInteger b = null;
//自定义数值, new 一个 BigInteger 对象并初始化为1
System.out.println("-----自定义数值初始化-----");
BigInteger c = new BigInteger("1");
BigInteger d = BigInteger.valueOf(1);
System.out.println(c);
System.out.println(d);

//BigInteger 静态成员,不可修改(可大致对比 C/C++ 中的全局变量+ const,使用时不用新 new 一个BigInteger对象)
System.out.println("-----内置数如下-----");
System.out.println(BigInteger.ZERO);
System.out.println(BigInteger.ONE);
System.out.println(BigInteger.TWO);
System.out.println(BigInteger.TEN);

//控制台读入
Scanner in = new Scanner(System.in);
//当输入不为EOF的时候持续读入,ctrl + D 结束输入
while (in.hasNext()){
a =in.nextBigInteger();
b = in.nextBigInteger();
}
//加
BigInteger res = a.add(b);
//在 Java 中,可以用 '+' 拼接字符串.不是字符串的对象会自动调用 toString 方法将其转为字符串
System.out.println("加法结果是" + res);
//减
res = a.subtract(b);
System.out.println("减法结果是"+res);
//乘
res = a.multiply(b);
System.out.println("乘法结果是"+res);
//除 ,会略去小数位(相当于整数除法),不建议使用
res = a.divide(res);
System.out.println("除法结果是"+res);


System.out.println("用 get 赋值");
BigInteger buf = new BigInteger("23");
a = get(buf);
System.out.println("赋值后a的值:"+ a);
//改一下 buf 的值后再看一下 a 的值
buf = buf.add(res);
System.out.println("更改buf后a的值:"+a);
System.out.println("buf的值" + buf);

//讲 a 转成 int
int va = a.intValue();
System.out.println(va);
}
}

BigDecimal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* @ClassName Main
* @Description TODO
* @Author bestsort
* @Date 19-8-10 上午9:59
* @Version 1.0
*/

package domain;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//两种创建方法,不推荐第一种,可能会出现精度问题
BigDecimal a = BigDecimal.valueOf(0.555);
String val = "12.21321321312";
BigDecimal b = new BigDecimal(val);

//加减乘和BigInteger一样,不赘述了.主要说说除法

/*BigDecimal 在执行除法的时候需要手动指定精度和舍入
*不然当除不尽的时候会抛出异常
*
* 2 表示精确到小数点后第20位,RoundingMode.HALF_DOWN表示多余的位置四舍五入
* 此外还有其他舍入模式可参考 http://itmyhome.com/java-api/ 的BigDecimal部分
* */

BigDecimal res = a.divide(b,20, RoundingMode.HALF_DOWN);
BigDecimal s = new BigDecimal(0.005);
System.out.println(s.divide(BigDecimal.ONE,2,RoundingMode.HALF_DOWN));
System.out.println(res);
}
}
觉得文章不错的话可以请我喝一杯茶哟~
  • 本文作者: bestsort
  • 本文链接: https://bestsort.cn/2019/08/10/810/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-SA 许可协议。转载请注明出处!并保留本声明。感谢您的阅读和支持!
-------------本文结束感谢您的阅读-------------