BigDemical
BigDecimal类:不可变的、任意精度的有符号十进制数,可以解决数据丢失问题。
public static void main(String[] args) {System.out.println(0.09 + 0.01); // 0.09999999999999999System.out.println(1.0 - 0.32); // 0.6799999999999999System.out.println(1.015 * 100); // 101.49999999999999System.out.println(1.301 / 100); // 0.013009999999999999System.out.println(1.0 - 0.12); // 0.88System.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.10BigDecimal bd3 = new BigDecimal("1.0");BigDecimal bd4 = new BigDecimal("0.32");System.out.println("subtract:" + bd3.subtract(bd4));//subtract:0.68BigDecimal bd5 = new BigDecimal("1.015");BigDecimal bd6 = new BigDecimal("100");System.out.println("multiply:" + bd5.multiply(bd6));//multiply:101.500BigDecimal 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.013System.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:2System.out.println("remainder:" + bis[1]);//remainder:0}}
