BigDecimal的使用

本文探讨了在 Java 编程中使用 BigDecimal 类进行精确数值计算的重要性,并详细介绍了其构造函数、转换方法以及不同舍入模式的应用。此外,文章还提供了一个实用的 Arithmetic 工具类,用于实现精确的加法、减法、乘法和除法运算,以及如何进行小数位的四舍五入处理。

商业计算,我们都知道不能用float和double,因为他们无法进行精确计算。BigDecimal可以完善float和double类无法进行精确计算的缺憾。

另外一些基本数据类型,如int,float,double,long,和BigDecimal对象相互转换。很简单:

基本类型通过构造函数转换成对应的BigDecimal对象,而BigDecimal类提供了诸如intValue(), floatValue(), doubleValue(), longValue()方法来将BigDecimal对象转换成对应的值。

BigDecimal bd = null; bd.multiply(BigDecimal.valueOf(2));Exception in thread "main" java.lang.NullPointerException at com.alibaba.china.industrycenter.service.TT.main(TT.java:14)

BigDecimal 进行运算时,对象必须先初始化,不能为null

BigDecimal bd = BigDecimal.valueOf(11); bd.multiply(BigDecimal.valueOf(2)); System.out.println(bd.doubleValue());

此时的结果是:11.0

运算的结果并不是存在当前的对象中,而是以返回值的形式

BigDecimal bd = BigDecimal.valueOf(11); bd = bd.multiply(BigDecimal.valueOf(2)); System.out.println(bd.doubleValue());


此时的结果是:22.0

ROUND_HALF_UP: 遇到.5的情况时往上近似,例: 1.5 ->;2
ROUND_HALF_DOWN : 遇到.5的情况时往下近似,例: 1.5 ->;1

BigDecimal a = new BigDecimal(1.5);
System.out.println("down="+a.setScale(0,BigDecimal.ROUND_HALF_DOWN)+"\tup="+a.setScale(0,BigDecimal.ROUND_HALF_UP));
结果:down=1up=2
看这个例子就明白了!

其他参数说明

ROUND_CEILING
如果 BigDecimal 是正的,则做 ROUND_UP 操作;如果为负,则做 ROUND_DOWN 操作。
ROUND_DOWN
从不在舍弃(即截断)的小数之前增加数字。
ROUND_FLOOR
如果 BigDecimal 为正,则作 ROUND_UP ;如果为负,则作 ROUND_DOWN 。
ROUND_HALF_DOWN
若舍弃部分> .5,则作 ROUND_UP;否则,作 ROUND_DOWN 。
ROUND_HALF_EVEN
如果舍弃部分左边的数字为奇数,则作 ROUND_HALF_UP ;如果它为偶数,则作 ROUND_HALF_DOWN 。
ROUND_HALF_UP
若舍弃部分>=.5,则作 ROUND_UP ;否则,作 ROUND_DOWN 。
ROUND_UNNECESSARY
该“伪舍入模式”实际是指明所要求的操作必须是精确的,,因此不需要舍入操作。
ROUND_UP
总是在非 0 舍弃小数(即截断)之前增加数字。


一个常用的Util工具类

public class Arith { //默认除法运算精度 private static final int DEF_DIV_SCALE = 10; //这个类不能实例化 private Arith() { ; } /** * 提供精确的加法运算。 * @param v1 被加数 * @param v2 加数 * @return 两个参数的和 */ public static double add(double v1,double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.add(b2).doubleValue(); } /** * 提供精确的减法运算。 * @param v1 被减数 * @param v2 减数 * @return 两个参数的差 */ public static double sub(double v1,double v2){ BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.subtract(b2).doubleValue(); } /** * 提供精确的乘法运算。 * @param v1 被乘数 * @param v2 乘数 * @return 两个参数的积 */ public static double mul(double v1,double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.multiply(b2).doubleValue(); } /** * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 * 小数点以后10位,以后的数字四舍五入。 * @param v1 被除数 * @param v2 除数 * @return 两个参数的商 */ public static double div(double v1,double v2) { return div(v1,v2,DEF_DIV_SCALE); } /** * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 * 定精度,以后的数字四舍五入。 * @param v1 被除数 * @param v2 除数 * @param scale 表示表示需要精确到小数点以后几位。 * @return 两个参数的商 */ public static double div(double v1,double v2,int scale) { if(scale<0) { throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); } /** * 提供精确的小数位四舍五入处理。 * @param v 需要四舍五入的数字 * @param scale 小数点后保留几位 * @return 四舍五入后的结果 */ public static double round(double v,int scale) { if(scale<0) { throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDecimal b = new BigDecimal(Double.toString(v)); BigDecimal one = new BigDecimal("1"); return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); } }



BigDecimal类是Java中处理高精度数值运算的强大工具,可执行精确的数学运算,避免浮点数的舍入误差,在金融和科学计算等需要高精度的场合不可或缺。以下是其常见使用方法: ### 初始化BigDecimal对象 可使用不同的构造方法来初始化。例如,使用`new BigDecimal(double)`和`new BigDecimal(String)`: ```java import java.math.BigDecimal; public class BigDecimalInitialization { public static void main(String[] args) { BigDecimal a = new BigDecimal(0.1); System.out.println("a values is:" + a); System.out.println("====================="); BigDecimal b = new BigDecimal("0.1"); System.out.println("b values is:" + b); } } ``` 这里使用`new BigDecimal(String)`能更精确地表示数值,因为`new BigDecimal(double)`可能会有舍入误差[^2]。 ### 基本数学运算 提供了一系列方法进行加法、减法、乘法和除法运算: ```java import java.math.BigDecimal; public class BigDecimalMathOperations { public static void main(String[] args) { BigDecimal num1 = new BigDecimal("130.512"); BigDecimal num2 = new BigDecimal("15.7"); // 加法 BigDecimal sum = num1.add(num2); System.out.println("加法结果: " + sum); // 减法 BigDecimal difference = num1.subtract(num2); System.out.println("减法结果: " + difference); // 乘法 BigDecimal product = num1.multiply(num2); System.out.println("乘法结果: " + product); // 除法(四舍五入保留2位小数) BigDecimal quotient = num1.divide(num2, 2, java.math.RoundingMode.HALF_UP); System.out.println("除法结果: " + quotient); } } ``` 上述代码展示了使用`add`、`subtract`、`multiply`和`divide`方法进行基本数学运算,除法时指定了保留小数位数和舍入模式[^1]。 ### 比较大小 通过`compareTo(BigDecimal)`方法来比较大小: ```java import java.math.BigDecimal; import org.junit.Test; public class BigDecimalComparison { @Test public void test4() { BigDecimal a = new BigDecimal("1"); BigDecimal b = new BigDecimal("2"); BigDecimal c = new BigDecimal("1"); int result1 = a.compareTo(b); int result2 = a.compareTo(c); int result3 = b.compareTo(a); System.out.println(result1); // -1 System.out.println(result2); // 0 System.out.println(result3); // 1 } } ``` 使用该方法时,若返回值为 -1 表示小于,0 表示等于,1 表示大于。需注意不能使用`equals`方法来比较大小,同时使用BigDecimal性能比`double`和`float`差,处理庞大、复杂运算时尤为明显,要根据实际需求选择使用哪种类型[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值