BigDecimal数据处理方法总结
前言
BigDecimal
是Java编程语言中位于
java.math包
中的一个类,主要用于进行高精度的十进制数计算。它提供了对任意精度的十进制数进行精确计算的能力,适用于需要保持精度和执行准确计算的场景
BigDecimal使用基于整数的表示方法,通过存储和处理数值的每一位来避免精度丢失。这使得它可以表示极大或极小的数字,并执行准确的计算。与基本的浮点数类型(如float和double)不同,BigDecimal通过调用相应的方法来进行数学运算,而不是使用传统的+、-、*、/等算术运算符
。
BigDecimal广泛应用于金融领域、货币计算、税务计算、精确计算需求以及其他需要保持精度和执行准确计算的场景。由于BigDecimal对象是不可变的,每个操作都会产生一个新的BigDecimal对象作为结果,这在某些情况下可能会影响性能。
1.BigDecimal数值运算
BigDecimal a = new BigDecimal("10.123");
BigDecimal b= new BigDecimal("2.123");//加法 BigDecimal addResult =a.add(b);
System.out.println("加法结果: " +addResult);//减法 BigDecimal subtractResult =a.subtract(b);
System.out.println("减法结果: " +subtractResult);//乘法 BigDecimal multiplyResult =a.multiply(b);
System.out.println("乘法结果: " +multiplyResult);//除法,并设置舍入模式为四舍五入 BigDecimal divideResult = a.divide(b, 2, RoundingMode.HALF_UP);
System.out.println("除法结果: " + divideResult);
2.bigDecimal数据转换
//1.int转BigDecimal int intValue = 10;
BigDecimal intToBigDecimal= newBigDecimal(intValue);
System.out.println("int转BigDecimal: " +intToBigDecimal);//2.double转BigDecimal double doubleValue = 10.123;
BigDecimal doubleToBigDecimal= newBigDecimal(doubleValue);
System.out.println("double转BigDecimal: " +doubleToBigDecimal);//3.String转BigDecimal String stringValue = "10.123";
BigDecimal stringToBigDecimal= newBigDecimal(stringValue);
System.out.println("String转BigDecimal: " +stringToBigDecimal);//long转BigDecimal long longValue = 10L;
BigDecimal longToBigDecimal= newBigDecimal(longValue);
System.out.println("long转BigDecimal: " + longToBigDecimal);
3.bigDecimal精度处理
//小数点的处理 BigDecimal decimal = new BigDecimal("10.123456789");
System.out.println("原始数据: " +decimal);//截取小数点后两位 BigDecimal decimal2 = decimal.setScale(2, RoundingMode.HALF_UP);
System.out.println("截取小数点后两位: " +decimal2);//截取小数点后四位 BigDecimal decimal4 = decimal.setScale(4, RoundingMode.HALF_UP);
System.out.println("截取小数点后四位: " +decimal4);//截取小数点后六位 (超过6位的小数点将被舍弃) BigDecimal decimal6 = decimal.setScale(6, RoundingMode.HALF_UP);
System.out.println("截取小数点后六位: " +decimal6);//截取小数点后八位 (超过8位的小数点将被舍弃) BigDecimal decimal8 = decimal.setScale(8, RoundingMode.HALF_UP);
System.out.println("截取小数点后八位: " +decimal8);//直接删除多余的小数位 BigDecimal test = new BigDecimal("9.56666");//直接删除多余的小数位 System.out.println("删除多余的小数位: " + test.setScale(2, BigDecimal.ROUND_DOWN));//四舍五入 BigDecimal test2 = new BigDecimal("9.56666");//四舍五入 System.out.println("四舍五入: " + test2.setScale(2, BigDecimal.ROUND_HALF_UP));double i = 3.856;//舍掉小数取整 System.out.println("舍掉小数取整:Math.floor(3.856)=" + (int) Math.floor(i));//四舍五入取整 System.out.println("四舍五入取整:(3.856)=" + new BigDecimal(i).setScale(0, BigDecimal.ROUND_HALF_UP));//四舍五入保留两位小数 System.out.println("四舍五入取整:(3.856)=" + new BigDecimal(i).setScale(2, BigDecimal.ROUND_HALF_UP));//凑整,取上限 System.out.println("凑整:Math.ceil(3.856)=" + (int) Math.ceil(i));//舍掉小数取整 System.out.println("舍掉小数取整:Math.floor(-3.856)=" + (int) Math.floor(-i));//四舍五入取整 System.out.println("四舍五入取整:(-3.856)=" + new BigDecimal(-i).setScale(0, BigDecimal.ROUND_HALF_UP));//四舍五入保留两位小数 System.out.println("四舍五入取整:(-3.856)=" + new BigDecimal(-i).setScale(2, BigDecimal.ROUND_HALF_UP));//凑整,取上限 System.out.println("凑整(-3.856)=" + (int) Math.ceil(-i));
4.bigDecimal的比较
BigDecimal a1 = new BigDecimal("10.123");
BigDecimal b1= new BigDecimal("2.123");//等于 System.out.println(a1.compareTo(b1) == 0);//大于 System.out.println(a1.compareTo(b1) > 0);//小于 System.out.println(a1.compareTo(b1) < 0);//大于等于 System.out.println(a1.compareTo(b1) >= 0);//小于等于 System.out.println(a1.compareTo(b1) <= 0);
5.bigDecimal的其他常用方法和函数
BigDecimal a2 = new BigDecimal("10.123");
BigDecimal b2= new BigDecimal("2.123");//绝对值 System.out.println("绝对值: " +a2.abs());//向上取整 System.out.println("向上取整: " +Math.ceil(a2.doubleValue()));//向下取整 System.out.println("向下取整: " +Math.floor(a2.doubleValue()));//四舍五入 System.out.println("四舍五入: " + a2.setScale(2, BigDecimal.ROUND_HALF_UP));//取整 System.out.println("取整: " + a2.setScale(0, BigDecimal.ROUND_HALF_UP));//取余 System.out.println("取余: " +a2.remainder(b2));//最大值 System.out.println("最大值: " +a2.max(b2));//最小值 System.out.println("最小值: " +a2.min(b2));//平方根 System.out.println("平方根: " +Math.sqrt(a2.doubleValue()));//正弦 System.out.println("正弦: " +Math.sin(a2.doubleValue()));//余弦 System.out.println("余弦: " +Math.cos(a2.doubleValue()));//正切 System.out.println("正切: " +Math.tan(a2.doubleValue()));//自然对数 System.out.println("自然对数: " +Math.log(a2.doubleValue()));//常用函数 System.out.println("常用函数: " +Math.exp(a2.doubleValue()));//百分数 System.out.println("百分数: " + a2.movePointLeft(2));//科学计数法 System.out.println("科学计数法: " +a2.toEngineeringString());//格式化输出 System.out.printf("格式化输出: " + "%.2f", a2.doubleValue());
6.bigdecimal精度丢失问题
//BigDecimal类用于精确的十进制数值计算。当使用BigDecimal进行运算时,//如果不正确处理精度模式(如ROUND_HALF_UP),可能会导致精度失去控制,即数值并非预期的结果。//解决方法://1.在进行加减乘除等运算时,确保正确设置BigDecimal的精度和舍入模式。//2.如果需要对BigDecimal对象进行多次运算,可以使用BigDecimal的setScale方法设置统一的精度和舍入模式。//3.在创建BigDecimal对象时,如果使用基本类型double作为参数,应该使用BigDecimal的valueOf方法,而不是new BigDecimal(double),因为后者可能会导致精度问题。 BigDecimal bigDecimal1 = new BigDecimal("1.234");
BigDecimal bigDecimal2= new BigDecimal("5.678");//正确设置舍入模式和精度:结果保留3位小数,并进行四舍五入 BigDecimal result = bigDecimal1.add(bigDecimal2).setScale(3, RoundingMode.HALF_UP);
System.out.println("结果: " +result);//bigdecimal精度格式化问题://BigDecimal类提供了toPlainString方法,可以将BigDecimal对象转换为字符串,//但是该方法并不提供精度控制,如果需要精度控制,可以使用BigDecimal的toString方法。//另外,BigDecimal类提供了format方法,可以格式化BigDecimal对象,//该方法可以指定输出的格式,包括整数位数、小数位数、是否显示符号、是否使用科学计数法等。 DecimalFormat df = new DecimalFormat("#,###.#################");
DecimalFormat df01= new DecimalFormat("#0.00");
BigDecimal bigDecimal3= new BigDecimal("1234567890.1234567890");//格式化输出: 1234567890.1234567890 System.out.println("格式化输出: " +bigDecimal3.toPlainString());//格式化输出: 123,456,789,0.1234567890 System.out.println("格式化输出: " +df.format(bigDecimal3.doubleValue()));
System.out.println("格式化输出: " + df01.format(bigDecimal3.doubleValue()));