最近做项目的时候遇到了这个数据类型,也踩了一些坑,也对这个数据类型有了一个初步的了解。
Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。
简单来说,就是提供浮点数的精确计算功能。
以下图片来自于:百度百科
float,double类型转换为bigdecimal类型的时候,一定要先转换为string类型,在转换为bigdecimal类型,否则精度过高
转换的方法:
double c=57.3;
BigDecimal decimalC=new BigDecimal(Double.toString(c));
BigDecimal decimalD=BigDecimal.valueOf(c);
具体详情参考链接:Java中double转BigDecimal的注意事项
4.1 DecimalFormat
BigDecimal zyCost=new BigDecimal(0.99999);
DecimalFormat df = new DecimalFormat("#0.00");
DecimalFormat dfint = new DecimalFormat("#0");
System.out.println(df.format(zyCost));
System.out.println( dfint .format(zyCost));
// 注意:此时的数据类型已经不再是BigDecimal了
4.2 RoundingMode
RoundingMode是一个枚举类,常见常量有
UP,DOWN,CEILING,FLOOR,HALF_UP,HALF_DOWN,HALF_EVEN,UNNECESSARY
常量解释:
UP 进位处理, 如2.124变为2.13, 2.125变为2.13
DOWN 截位处理, 如2.124变为2.12, 2.125变为2.12
CEILING 进位处理, 如2.124变为2.13, 2.125变为2.13
FLOOR 进位处理, 如2.124变为2.12, 2.125变为2.12
HALF_UP 四舍五入(>= 0.5 进位,否则舍位) 如2.124变为2.12, 2.125变为2.13
HALF_DOWN 进位处理(>0.5 进位,否则舍位) 如2.125变为2.12, 2.126变为2.13
HALF_EVEN 如果舍弃部分左边的数字为奇数,则舍入行为同 RoundingMode.HALF_UP;如果为偶数,则舍入行为同RoundingMode.HALF_DOWN
UNNECESSARY 用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。如果对生成精确结果的操作指定此舍入模式,则抛出 ArithmeticException。
代码演示:
System.out.println(new BigDecimal("2.120").setScale(2, RoundingMode.UP));
System.out.println(new BigDecimal("2.120").setScale(2, RoundingMode.DOWN));
System.out.println(new BigDecimal("2.120").setScale(2, RoundingMode.CEILING));
System.out.println(new BigDecimal("2.120").setScale(2, RoundingMode.FLOOR));
System.out.println(new BigDecimal("2.120").setScale(2, RoundingMode.HALF_UP));
System.out.println(new BigDecimal("2.120").setScale(2, RoundingMode.HALF_DOWN));
System.out.println(new BigDecimal("2.120").setScale(2, RoundingMode.HALF_EVEN));
System.out.println(new BigDecimal("2.124").setScale(2, RoundingMode.UP));
System.out.println(new BigDecimal("2.124").setScale(2, RoundingMode.DOWN));
System.out.println(new BigDecimal("2.124").setScale(2, RoundingMode.CEILING));
System.out.println(new BigDecimal("2.124").setScale(2, RoundingMode.FLOOR));
System.out.println(new BigDecimal("2.124").setScale(2, RoundingMode.HALF_UP));
System.out.println(new BigDecimal("2.124").setScale(2, RoundingMode.HALF_DOWN));
System.out.println(new BigDecimal("2.124").setScale(2, RoundingMode.HALF_EVEN));
System.out.println(new BigDecimal("2.125").setScale(2, RoundingMode.UP));
System.out.println(new BigDecimal("2.125").setScale(2, RoundingMode.DOWN));
System.out.println(new BigDecimal("2.125").setScale(2, RoundingMode.CEILING));
System.out.println(new BigDecimal("2.125").setScale(2, RoundingMode.FLOOR));
System.out.println(new BigDecimal("2.125").setScale(2, RoundingMode.HALF_UP));
System.out.println(new BigDecimal("2.125").setScale(2, RoundingMode.HALF_DOWN));
System.out.println(new BigDecimal("2.125").setScale(2, RoundingMode.HALF_EVEN));
System.out.println(new BigDecimal("2.1").setScale(2, RoundingMode.UP));
System.out.println(new BigDecimal("2.1").setScale(2, RoundingMode.DOWN));
System.out.println(new BigDecimal("2.1").setScale(2, RoundingMode.CEILING));
System.out.println(new BigDecimal("2.1").setScale(2, RoundingMode.FLOOR));
System.out.println(new BigDecimal("2.1").setScale(2, RoundingMode.HALF_UP));
System.out.println(new BigDecimal("2.1").setScale(2, RoundingMode.HALF_DOWN));
System.out.println(new BigDecimal("2.1").setScale(2, RoundingMode.HALF_EVEN));
System.out.println(new BigDecimal("2.1").setScale(2, RoundingMode.UNNECESSARY));
BigDecimal.ROUND_DOWN 直接删除多余的小数位,如2.35会变成2.3
BigDecimal.ROUND_UP 进位处理,如2.124会变成2.13,2.125会变成2.13
BigDecimal.ROUND_HALF_UP 四舍五入,
代码演示:
System.out.println(new BigDecimal("2.120").setScale(2,BigDecimal.ROUND_DOWN));
System.out.println(new BigDecimal("2.120").setScale(2,BigDecimal.ROUND_UP));
System.out.println(new BigDecimal("2.120").setScale(2,BigDecimal.ROUND_HALF_UP));
System.out.println(new BigDecimal("2.124").setScale(2,BigDecimal.ROUND_DOWN));
System.out.println(new BigDecimal("2.124").setScale(2,BigDecimal.ROUND_UP));
System.out.println(new BigDecimal("2.124").setScale(2,BigDecimal.ROUND_HALF_UP));
System.out.println(new BigDecimal("2.125").setScale(2,BigDecimal.ROUND_DOWN));
System.out.println(new BigDecimal("2.125").setScale(2,BigDecimal.ROUND_UP));
System.out.println(new BigDecimal("2.125").setScale(2,BigDecimal.ROUND_HALF_UP));
System.out.println(new BigDecimal("2.1").setScale(2,BigDecimal.ROUND_DOWN));
System.out.println(new BigDecimal("2.1").setScale(2,BigDecimal.ROUND_UP));
System.out.println(new BigDecimal("2.1").setScale(2,BigDecimal.ROUND_HALF_UP));
参考链接:DecimalFormat对数值格式化的舍入问题——RoundingMode
0在BigDecimal中有固定的常量标识
BigDecimal cost=BigDecimal.ZERO;
BigDecimal zyCost=new BigDecimal(0.0000);
BigDecimal cost=new BigDecimal(5);
BigDecimal sum=zyCost.add(cost).subtract(cost);
DecimalFormat dfint = new DecimalFormat("#0");
System.out.println(dfint.format(sum));
System.out.println(zyCost.equals(0));
System.out.println(zyCost.equals(new BigDecimal(0)));
System.out.println(sum.equals(BigDecimal.ZERO));
System.out.println(dfint.format(sum).equals(BigDecimal.ZERO));
System.out.println(new BigDecimal(dfint.format(zyCost)).equals(BigDecimal.ZERO));
// 比较的数值类型一定要一样