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 = new BigDecimal(intValue);
        System.out.println("int转BigDecimal: " + intToBigDecimal);

        // 2.double转BigDecimal
        double doubleValue = 10.123;
        BigDecimal doubleToBigDecimal = new BigDecimal(doubleValue);
        System.out.println("double转BigDecimal: " + doubleToBigDecimal);

        // 3.String转BigDecimal
        String stringValue = "10.123";
        BigDecimal stringToBigDecimal = new BigDecimal(stringValue);
        System.out.println("String转BigDecimal: " + stringToBigDecimal);

        // long转BigDecimal
        long longValue = 10L;
        BigDecimal longToBigDecimal = new BigDecimal(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()));
相关推荐
考虑考虑2 小时前
Jpa使用union all
java·spring boot·后端
用户3721574261352 小时前
Java 实现 Excel 与 TXT 文本高效互转
java
浮游本尊3 小时前
Java学习第22天 - 云原生与容器化
java
渣哥5 小时前
原来 Java 里线程安全集合有这么多种
java
间彧5 小时前
Spring Boot集成Spring Security完整指南
java
间彧5 小时前
Spring Secutiy基本原理及工作流程
java
Java水解6 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
洛小豆8 小时前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学9 小时前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端
ytadpole9 小时前
Spring Cloud Gateway:一次不规范 URL 引发的路由转发404问题排查
java·后端