在Java中,由CPU原生提供的整型最大范围是long型整数(64位)。使用long型整数可以直接通过CPU指令进行计算,速度非常快。
若使用的整数范围超过了long型怎么办?
java.math.BigInteger就是用来表示任意大小的整数的不变类。其内部用一个数组int[]来模拟一个大整数。
引入类:
import java.math.BigInteger;
BigInteger bi = new BigInteger("1234567890"); //创建方法
对BigInteger做运算的时候,只能使用实例方法,常用的有:
add() 、subtract()、multiply() 、divide()pow()bytevalue()、shortValue()、intValue()、longValue()、floatValue()、doublevalue()
这些都是继承自Number类的函数,将BigInteger转换为基本类型。
如果BigInteger表示的范围超过了基本类型的范围,转换时将丢失高位信息,即结果不一定是准确的。
如果BigInteger的值甚至超过了float的最大范围(3.4x1038),那么floatValue()返回的值为Infinity。intValueExact()、longValueExact() :将BigInteger转换为int、long类型
优点在于:如果超出了long型的范围,会报错ArithmeticException,因此若转换成功,则结果一定是准确的。
BigDecimal
BigDecimal可以表示一个任意大小且精度完全准确的浮点数。
本质上,一个BigDecimal是通过一个BigInteger和一个scale来表示的,即BigInteger表示一个完整的整数,而scale表示小数位数。
引入类:
import java.math.BigDecimal;
创建对象:
BigDecimal bd = new BigDecimal("123.4567");
常用函数:
scale(): 返回小数位数(1.00的小数位数为2)stripTrailingZeros():返回一个新的BigDecimal对象:与原来相等但去掉了末尾的0(无论是不是小数部分)
若scale()返回负数,例如-2,则表示这个数是个整数,并且末尾有2个0。
BigDecimal d1 = new BigDecimal("123.4500");
BigDecimal d2 = d1.stripTrailingZeros();
System.out.println(d1.scale()); // 4
System.out.println(d2.scale()); // 2,因为去掉了00
BigDecimal d3 = new BigDecimal("1234500");
BigDecimal d4 = d3.stripTrailingZeros();
System.out.println(d3.scale()); // 0
System.out.println(d4.scale()); // -2
可以对一个BigDecimal设置它的scale,如果精度比原始值低,那么按照指定的方法进行省略(四舍五入或者直接截断):
引入类:
import java.math.RoundingMode;
BigDecimal d1 = new BigDecimal("123.456789");
BigDecimal d2 = d1.setScale(4, RoundingMode.HALF_UP); // 四舍五入,123.4568
BigDecimal d3 = d1.setScale(4, RoundingMode.DOWN); // 直接截断,123.4567
//System.out.println(d2);
//System.out.println(d3);
对BigDecimal做加、减、乘时,精度不会丢失,但是做除法时,存在无法除尽的情况,这时就必须指定精度以及截断方式:
BigDecimal d1 = new BigDecimal("123.456");
BigDecimal d2 = new BigDecimal("23.456789");
BigDecimal d3 = d1.divide(d2); // 报错:ArithmeticException,因为除不尽
BigDecimal d4 = d1.divide(d2, 10, RoundingMode.HALF_UP); // 保留10位小数并四舍五入
System.out.println(d4);
divideAndRemainder():对BigDecimal做除法的同时求余数:
BigDecimal n = new BigDecimal("12.345");
BigDecimal m = new BigDecimal("0.12");
BigDecimal[] dr = n.divideAndRemainder(m);
System.out.println(dr[0]); // 102
System.out.println(dr[1]); // 0.105
// dr[0]是商,dr[1]是余数。商总是整数,余数不会大于除数。
if (dr[1].signum() == 0) { //n被m整除 (通过判断余数的符号:正、负、零)
}
equals():比较两个BigDecimal的值是否相等(不要用)
特别注意,使用equals()方法不但要求两个BigDecimal的值相等,还要求它们的scale()相等。
因此应使用compareTo()compareTo():返回负数、正数和0,分别表示小于、大于和等于。



