BigDemical
BigDecimal类:不可变的、任意精度的有符号十进制数,可以解决数据丢失问题。
public static void main(String[] args) {
System.out.println(0.09 + 0.01); // 0.09999999999999999
System.out.println(1.0 - 0.32); // 0.6799999999999999
System.out.println(1.015 * 100); // 101.49999999999999
System.out.println(1.301 / 100); // 0.013009999999999999
System.out.println(1.0 - 0.12); // 0.88
System.out.println(new BigDecimal(12.45));// 12.44999999999999928945726423989981412
// 上面这个12.45,其实是double类型的,容易丢失精度
System.out.println(new BigDecimal("12.45"));// 12.45
}
结果和我们想的有一点点不一样,这是因为浮点数类型的数据存储和整数不一样导致的。 它们大部分的时候,都是带有有效数字位。由于在运算的时候,float类型和double很容易丢失精度, 所以,为了能精确的表示、计算浮点数,Java提供了BigDecimal。
BigDecimal的常用成员方法:
public BigDecimal(String val) //构造方法
public BigDecimal add(BigDecimal augend) //加
public BigDecimal subtract(BigDecimal subtrahend)//减
public BigDecimal multiply(BigDecimal multiplicand) //乘
public BigDecimal divide(BigDecimal divisor) //除
public BigDecimal divide(BigDecimal divisor,int scale,int roundingMode)//除法,scale:几位小数,roundingMode:如何舍取
使用BigDecimal改进
public static void main(String[] args) {
/*System.out.println(0.09 + 0.01);
System.out.println(1.0 - 0.32);
System.out.println(1.015 * 100);
System.out.println(1.301 / 100);
System.out.println(1.0 - 0.12);*/
BigDecimal bd1 = new BigDecimal("0.09");
BigDecimal bd2 = new BigDecimal("0.01");
System.out.println("add:" + bd1.add(bd2));//add:0.10
BigDecimal bd3 = new BigDecimal("1.0");
BigDecimal bd4 = new BigDecimal("0.32");
System.out.println("subtract:" + bd3.subtract(bd4));//subtract:0.68
BigDecimal bd5 = new BigDecimal("1.015");
BigDecimal bd6 = new BigDecimal("100");
System.out.println("multiply:" + bd5.multiply(bd6));//multiply:101.500
BigDecimal bd7 = new BigDecimal("1.301");
BigDecimal bd8 = new BigDecimal("100");
System.out.println("divide:" + bd7.divide(bd8));//divide:0.01301
//四舍五入
System.out.println("divide:"
+ bd7.divide(bd8, 3, BigDecimal.ROUND_HALF_UP));//保留三位有效数字
//divide:0.013
System.out.println("divide:"
+ bd7.divide(bd8, 8, BigDecimal.ROUND_HALF_UP));//保留八位有效数字
//divide:0.01301000
}
舍入模式
ROUND_UP
- 定义:远离零方向舍入。
- 解释:始终对非零舍弃部分前面的数字加 1。注意,此舍入模式始终不会减少计算值的绝对值。
- 图示:
- 非0时,舍弃小数后(整数部分)加1,比如12.49结果为13,-12.49结果为 -13
ROUND_CEILING:
- 定义:向正无限大方向舍入。
- 解释:正数,则做 ROUND_UP 操作;负数,则做 ROUND_DOWN 操作 。注意,此舍入模式始终不会减少计算值。
- 图示:
ROUND_DOWN:直接舍弃小数
- 定义:向零方向舍入。
- 解释:从不对舍弃部分前面的数字加 1(即截尾)。注意,此舍入模式始终不会增加计算值的绝对值。
- 图示:
ROUND_FLOOR:
- 定义:向负无限大方向舍入。
- 解释:正数,则做 ROUND_DOWN 操作;负数,则做 ROUND_UP 操作。 注意,此舍入模式始终不会增加计算值。
- 图示:
ROUND_HALF_UP:四舍五入(取更近的整数)
- 定义:向最接近的数字方向舍入,如果与两个相邻数字的距离相等,则向上舍入。
- 解释:如果被舍弃部分 >= 0.5,则舍入行为同 RoundingMode.UP;否则舍入行为同RoundingMode.DOWN。注意,此舍入模式就是四舍五入。
- 图示:
ROUND_HALF_DOWN:跟ROUND_HALF_UP 差别仅在于0.5时会向下取整
- 定义:向最接近的数字方向舍入,如果与两个相邻数字的距离相等,则向下舍入。
- 解释:如果被舍弃部分 > 0.5,则舍入行为同 RoundingMode.UP;否则舍入行为同RoundingMode.DOWN。注意,此舍入模式就是通常讲的五舍六入。
- 图示:
ROUND_HALF_EVEN:取最近的偶数
- 定义:向最接近数字方向舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。
- 解释:如果舍弃部分左边的数字为奇数,则舍入行为同 RoundingMode.HALF_UP;如果为偶数,则舍入行为同RoundingMode.HALF_DOWN。
- 注意,在重复进行一系列计算时,根据统计学,此舍入模式可以在统计上将累加错误减到最小。此舍入模式也称为“银行家舍入法”,主要在美国使用。此舍入模式类似于 Java 中对float 和double 算法使用的舍入策略。
- 图示:
ROUND_UNNECESSARY:不需要取整,如果存在小数位,就抛ArithmeticException 异常
- 定义:用于断言请求的操作具有精确结果,因此不发生舍入。
- 解释:计算结果是精确的,不需要舍入,若结果的小数位数>要求保留的位数,抛出 ArithmeticException。
BigInteger
BigInteger:可以让超过Integer范围内的数据进行运算
public static void main(String[] args) {
Integer num = new Integer("2147483647");
System.out.println(num);
//Integer num2 = new Integer("2147483648");
// Exception in thread "main" java.lang.NumberFormatException: For input string: "2147483648"
//System.out.println(num2);
// 通过 BigIntege来创建对象
BigInteger num2 = new BigInteger("2147483648");
System.out.println(num2);
}
- BigInteger的常用成员方法:
public BigInteger add(BigInteger val) //加
public BigInteger subtract(BigInteger val) //减
public BigInteger multiply(BigInteger val) //乘
public BigInteger divide(BigInteger val) //除
public BigInteger[] divideAndRemainder(BigInteger val)//返回商和余数的数组
- 使用实例:
public class BigIntegerDemo {
public static void main(String[] args) {
Integer num = new Integer("2147483647");
System.out.println(num);
//Integer num2 = new Integer("2147483648");
// Exception in thread "main" java.lang.NumberFormatException: For input string: "2147483648"
//System.out.println(num2);
// 通过 BigIntege来创建对象
BigInteger num2 = new BigInteger("2147483648");
System.out.println(num2);
}
}
public class BigIntegerDemo2 {
public static void main(String[] args) {
BigInteger bi1 = new BigInteger("100");
BigInteger bi2 = new BigInteger("50");
// public BigInteger add(BigInteger val):加
System.out.println("add:" + bi1.add(bi2)); //add:150
// public BigInteger subtract(BigInteger Val):减
System.out.println("subtract:" + bi1.subtract(bi2));//subtract:50
// public BigInteger multiply(BigInteger val):乘
System.out.println("multiply:" + bi1.multiply(bi2));//multiply:5000
// public BigInteger divide(BigInteger val):除
System.out.println("divide:" + bi1.divide(bi2));//divide:2
// public BigInteger[] divideAndRemainder(BigInteger val):返回商和余数的数组
BigInteger[] bis = bi1.divideAndRemainder(bi2);
System.out.println("divide:" + bis[0]);//divide:2
System.out.println("remainder:" + bis[1]);//remainder:0
}
}