BigDecimal的使用
文档参考资料1地址:https://blog.csdn.net/qq_35868412/article/details/89029288
文档参考资料2地址:https://blog.csdn.net/haiyinshushe/article/details/82721234
目录
1 BigDecimal的构造方法
//1 BigDecimal的构造方法
BigDecimal intBD = new BigDecimal(1);
BigDecimal longBD = new BigDecimal(1L);
//禁止使用double的bigDecimal的构造方法
BigDecimal doubleBD = new BigDecimal(1.1111);
//结果:1.111099999999999976552089719916693866252899169921875
//以下为推荐模式
BigDecimal stringBD = new BigDecimal(Double.toString(1.1111));
BigDecimal strBD = BigDecimal.valueOf(1.1111);
2 四则运算
//2 四则运算
//add(BigDecimal) BigDecimal对象中的值相加,然后返回这个对象。
//subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象。
//multiply(BigDecimal) BigDecimal对象中的值相乘,然后返回这个对象。
//divide(BigDecimal) BigDecimal对象中的值相除,然后返回这个对象。
BigDecimal three = new BigDecimal(3);
BigDecimal nine = new BigDecimal(9);
BigDecimal add = three.add(nine);
System.out.println(add);
BigDecimal subtract = three.subtract(nine);
System.out.println(subtract);
BigDecimal multiply = three.multiply(nine);
System.out.println(multiply);
//BigDecimal divide = three.divide(nine);
//进行除法运算的时候,结果不能整除,有余数,这个时候会报java.lang.ArithmeticException:
//(BigDecimal divisor 除数, int scale 精确小数位, int roundingMode 舍入模式)
//结果保留两位小数且向下取整
BigDecimal result = new BigDecimal("9.99").multiply(new BigDecimal("0.5")).setScale(2, RoundingMode.DOWN);//4.99
3 八种舍入模式
//3 八种舍入模式
//3.1、ROUND_UP
// 舍入远离零的舍入模式。
// 在丢弃非零部分之前始终增加数字(始终对非零舍弃部分前面的数字加1)。
// 注意,此舍入模式始终不会减少计算值的大小。
BigDecimal divide = three.divide(nine,4, BigDecimal.ROUND_UP);
System.out.println(divide);
//结果: 0.3334
//3.2、ROUND_DOWN
//接近零的舍入模式。
//在丢弃某部分之前始终不增加数字(从不对舍弃部分前面的数字加1,即截短)。
//注意,此舍入模式始终不会增加计算值的大小。
divide = three.divide(nine,4, BigDecimal.ROUND_DOWN);
System.out.println(divide);
//结果: 0.3333
//3.3、ROUND_CEILING 接近正无穷大的舍入模式。
// 如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同;
// 如果为负,则舍入行为与 ROUND_DOWN 相同。
// 注意,此舍入模式始终不会减少计算值
divide = three.divide(nine,4, BigDecimal.ROUND_CEILING);
System.out.println(divide);
//结果: 0.3334
//3.4、ROUND_FLOOR
//接近负无穷大的舍入模式。
//如果 BigDecimal 为正,则舍入行为与 ROUND_DOWN 相同;
//如果为负,则舍入行为与 ROUND_UP 相同。
//注意,此舍入模式始终不会增加计算值。
divide = three.divide(nine,4, BigDecimal.ROUND_FLOOR);
System.out.println(divide);
//结果: 0.3333
//5、ROUND_HALF_UP
//向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。
//如果舍弃部分 >= 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同。
//注意,这是我们大多数人在小学时就学过的舍入模式(四舍五入)。
divide = three.divide(nine,4, BigDecimal.ROUND_HALF_UP);
System.out.println(divide);
//结果: 0.3333
//3.6、ROUND_HALF_DOWN
//向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为上舍入的舍入模式。
//如果舍弃部分 > 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同(五舍六入)。
divide = three.divide(nine,4, BigDecimal.ROUND_HALF_DOWN);
System.out.println(divide);
//结果: 0.3333
//3.7、ROUND_HALF_EVEN
//向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。
//如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同;
//如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。
//注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。
//此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况。
//如果前一位为奇数,则入位,否则舍去。
//以下例子为保留小数点1位,那么这种舍入方式下的结果。
//1.15>1.2 1.25>1.2
divide = three.divide(nine,4, BigDecimal.ROUND_HALF_EVEN);
System.out.println(divide);
//结果: 0.3333
//3.8、ROUND_UNNECESSARY
//断言请求的操作具有精确的结果,因此不需要舍入。
//结果不能整除,有余数,这个时候会报java.lang.ArithmeticException:
//divide = three.divide(nine,4, BigDecimal.ROUND_UNNECESSARY);
//System.out.println(divide);
//结果: ArithmeticException: Rounding necessary
4 推荐使用模式的枚举
//4 推荐使用模式的枚举
//4.1舍入远离零的舍入模式
divide = three.divide(nine,4,RoundingMode.UP);
//4.2接近零的舍入模式
divide = three.divide(nine,4,RoundingMode.DOWN);
//4.3接近正无穷大的舍入模式
divide = three.divide(nine,4,RoundingMode.CEILING);
//4.4接近负无穷大的舍入模式
divide = three.divide(nine,4,RoundingMode.FLOOR);
//4.5向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。
divide = three.divide(nine,4,RoundingMode.HALF_UP);
//4.6向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为上舍入的舍入模式
divide = three.divide(nine,4,RoundingMode.HALF_DOWN);
//4.7向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入
divide = three.divide(nine,4,RoundingMode.HALF_EVEN);
//4.8断言请求的操作具有精确的结果,因此不需要舍入
//divide = three.divide(nine,4,RoundingMode.UNNECESSARY);
5 BigDecimal转百分比
//5 BigDecimal转百分比
BigDecimal bigDecimal =BigDecimal.valueOf(0.3);
NumberFormat percent = NumberFormat.getPercentInstance();
//percent.setMinimumFractionDigits(2);
//结果: 30.00%
percent.setMaximumFractionDigits(2);
//结果: 30%
String percentage = percent.format(bigDecimal.doubleValue());
System.out.println(percentage);
6 测试代码
package com.saiyou.test;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
/**
* @author : lyn
* 技术点 :
* @description:
* @date : 2022/1/10 22:28
*/
public class BigDecimalTest {
public static void main(String[] args) {
//1 BigDecimal的构造方法
BigDecimal intBD = new BigDecimal(1);
BigDecimal longBD = new BigDecimal(1L);
//禁止使用double的bigDecimal的构造方法
BigDecimal doubleBD = new BigDecimal(1.1111);
//结果:1.111099999999999976552089719916693866252899169921875
//以下为推荐模式
BigDecimal stringBD = new BigDecimal(Double.toString(1.1111));
BigDecimal strBD = BigDecimal.valueOf(1.1111);
//2 四则运算
//add(BigDecimal) BigDecimal对象中的值相加,然后返回这个对象。
//subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象。
//multiply(BigDecimal) BigDecimal对象中的值相乘,然后返回这个对象。
//divide(BigDecimal) BigDecimal对象中的值相除,然后返回这个对象。
BigDecimal three = new BigDecimal(3);
BigDecimal nine = new BigDecimal(10);
BigDecimal add = three.add(nine);
System.out.println(add);
BigDecimal subtract = three.subtract(nine);
System.out.println(subtract);
BigDecimal multiply = three.multiply(nine);
System.out.println(multiply);
//BigDecimal divide = three.divide(nine);
//进行除法运算的时候,结果不能整除,有余数,这个时候会报java.lang.ArithmeticException:
//(BigDecimal divisor 除数, int scale 精确小数位, int roundingMode 舍入模式)
//3 八种舍入模式
//3.1、ROUND_UP
// 舍入远离零的舍入模式。
// 在丢弃非零部分之前始终增加数字(始终对非零舍弃部分前面的数字加1)。
// 注意,此舍入模式始终不会减少计算值的大小。
BigDecimal divide = three.divide(nine,4, BigDecimal.ROUND_UP);
System.out.println(divide);
//结果: 0.3334
//3.2、ROUND_DOWN
//接近零的舍入模式。
//在丢弃某部分之前始终不增加数字(从不对舍弃部分前面的数字加1,即截短)。
//注意,此舍入模式始终不会增加计算值的大小。
divide = three.divide(nine,4, BigDecimal.ROUND_DOWN);
System.out.println(divide);
//结果: 0.3333
//3.3、ROUND_CEILING 接近正无穷大的舍入模式。
// 如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同;
// 如果为负,则舍入行为与 ROUND_DOWN 相同。
// 注意,此舍入模式始终不会减少计算值
divide = three.divide(nine,4, BigDecimal.ROUND_CEILING);
System.out.println(divide);
//结果: 0.3334
//3.4、ROUND_FLOOR
//接近负无穷大的舍入模式。
//如果 BigDecimal 为正,则舍入行为与 ROUND_DOWN 相同;
//如果为负,则舍入行为与 ROUND_UP 相同。
//注意,此舍入模式始终不会增加计算值。
divide = three.divide(nine,4, BigDecimal.ROUND_FLOOR);
System.out.println(divide);
//结果: 0.3333
//5、ROUND_HALF_UP
//向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。
//如果舍弃部分 >= 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同。
//注意,这是我们大多数人在小学时就学过的舍入模式(四舍五入)。
divide = three.divide(nine,4, BigDecimal.ROUND_HALF_UP);
System.out.println(divide);
//结果: 0.3333
//3.6、ROUND_HALF_DOWN
//向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为上舍入的舍入模式。
//如果舍弃部分 > 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同(五舍六入)。
divide = three.divide(nine,4, BigDecimal.ROUND_HALF_DOWN);
System.out.println(divide);
//结果: 0.3333
//3.7、ROUND_HALF_EVEN
//向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。
//如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同;
//如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。
//注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。
//此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况。
//如果前一位为奇数,则入位,否则舍去。
//以下例子为保留小数点1位,那么这种舍入方式下的结果。
//1.15>1.2 1.25>1.2
divide = three.divide(nine,4, BigDecimal.ROUND_HALF_EVEN);
System.out.println(divide);
//结果: 0.3333
//3.8、ROUND_UNNECESSARY
//断言请求的操作具有精确的结果,因此不需要舍入。
//结果不能整除,有余数,这个时候会报java.lang.ArithmeticException:
//divide = three.divide(nine,4, BigDecimal.ROUND_UNNECESSARY);
//System.out.println(divide);
//结果: ArithmeticException: Rounding necessary
//4 推荐使用模式的枚举
//4.1舍入远离零的舍入模式
divide = three.divide(nine,4,RoundingMode.UP);
//4.2接近零的舍入模式
divide = three.divide(nine,4,RoundingMode.DOWN);
//4.3接近正无穷大的舍入模式
divide = three.divide(nine,4,RoundingMode.CEILING);
//4.4接近负无穷大的舍入模式
divide = three.divide(nine,4,RoundingMode.FLOOR);
//4.5向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。
divide = three.divide(nine,4,RoundingMode.HALF_UP);
//4.6向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为上舍入的舍入模式
divide = three.divide(nine,4,RoundingMode.HALF_DOWN);
//4.7向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入
divide = three.divide(nine,4,RoundingMode.HALF_EVEN);
//4.8断言请求的操作具有精确的结果,因此不需要舍入
//divide = three.divide(nine,4,RoundingMode.UNNECESSARY);
//5 BigDecimal转百分比
BigDecimal bigDecimal =BigDecimal.valueOf(0.3);
NumberFormat percent = NumberFormat.getPercentInstance();
//percent.setMinimumFractionDigits(2);
//结果: 30.00%
percent.setMaximumFractionDigits(2);
//结果: 30%
String percentage = percent.format(bigDecimal.doubleValue());
System.out.println(percentage);
}
}
注意:
禁止使用double的bigDecimal的构造方法,会丢失精度
BigDecimal doubleBD = new BigDecimal(1.1111);
//结果:1.111099999999999976552089719916693866252899169921875
7 BigDecimal的使用示例
比较大小
BigDecimal v1 = new BigDecimal(9);
BigDecimal v2 = new BigDecimal(10);
//比较大小 v1>v2 return 1 v1=v2 return 0 v1<v2 return -1
int result = v1.compareTo(v2);
System.out.println(result);
判断BigDecimal 类型的数字是否是整数
public boolean isInteger(BigDecimal number) {
return number.compareTo(number.setScale(0, BigDecimal.ROUND_DOWN)) == 0;
}
这个方法首先将这个 BigDecimal 类型的数字设置到小数点后0位(也就是舍去小数部分),然后比较原始数字和舍去小数部分的数字。如果这两个数字相等,那么原始数字就是整数。