为什么用BigDecimal
- 使用float、double及其对应的包装类时,运算精度可能不满足需求
- float最多只有7位有效数,则其精度为6-7位。
- double最多只有16位有效数,则其精度为15~16位。
- 使用float、double及其对应的包装类时,不便于对小数点以后的若干位进行截取四舍五入或相关处理
所以BigDecimal主要是用来解决误差问题(精度问题)
BigDecimal构造方法
通过静态方法创建BigDecimal对象
返回值类型 |
方法 |
说明 |
BigDecimal |
valueOf(double val) |
基于float / double类型的数据创建BigDecimal对象 |
BigDecimal |
valueOf(long val) |
基于byte/ short / int / long类型的数据创建BiqDecimal对象 |
BigDecimal常用API
返回值类型 |
方法 |
说明 |
BigDecimal |
add(BigDecimal augend) |
加法运算 |
BigDecimal |
subtract(BigDecimal subtrahend) |
减法运算 |
BigDecimal |
multiply(BigDecimal multiplicand) |
乘法运算 |
BigDecimal |
divide(BigDecimal divisor) |
除法运算 |
BigDecimal |
divide(BigDecimal divisor, int roundingMode) |
除法运算 |
BigDecimal |
divide(BiaDecimaldivisor,int scale, int roundinaMode) |
除法运算 |
BigDecimal |
remainder(BigDecimal divisor) |
求余运算 |
BigDecimal[] |
divideAndRemainder(BigDecimal divisor) |
除并求余运算 |
BigDecimal |
min(BigDecimal val) |
取最大值运算 |
BigDecimal |
max(BiqDecimal val) |
取最小值运算 |
解释:
- 在调用divide()方法时,使用roundingMode可以设置运算时的舍入模式
- 使用BigDecimal类中以ROUND为前缀的常量表示
- 例如: BigDecimal.ROUND_HALF_UP
关于除法运算的roundingMode
常量值 |
说明 |
ROUND_UP |
在丢弃非零部分之前始终增加数字(始终对非零舍弃部分前面的数字加1) |
ROUND_DOWN |
在丢弃某部分之前始终不增加数字(从不对舍弃部分前面的数字加1,即截短) |
ROUND_CEILING |
正数时,与ROUND_UP相同,负数时,与ROUND_DOWN相同 |
ROUND_FLOOR |
正数时,与ROUND_DOWN相同,负数时,与ROUND_UP相同 |
ROUND_HALF_UP |
满足四舍五入时,与ROUND_UP相同,否则,与ROUND_DOWN相同 |
ROUND_HALF_DOWN |
满足五舍六入时,与ROUND_UP相同,否则,与ROUND_DOWN相同 |
ROUND_HALF_EVEN |
若舍弃部分左侧为奇数,与ROUND_HALE_UP相同,否则,与ROUND_HALE_DOWN相同 |
ROUND_UNNECESSARY |
断言请求的操作具有精确的结果,因此不需要舍入 |
将BigDecimal转换为基本类型
返回值类型 |
方法 |
说明 |
int |
intValue() |
转换为int,可能丢失精度 |
int |
intValueExact() |
转换为int,若丢失精度则抛出ArithmeticException |
long |
longValue() |
转换为long,可能丢失精度 |
long |
longValueExact() |
转换为long,若丢失精度则抛出ArithmeticException |
float |
floatValue() |
转换为float,可能丢失精度 |
double |
doubleValue() |
转换为double,可能丢失精度 |
byte |
byteValueExtra() |
转换为byte,若丢失精度则抛出ArithmeticException |
short |
shortValueExact () |
转换为short,若丢失精度则抛出ArithmeticException |
注意:在进行转换之前,应该明确是否会丢失精度,避免转换结果不符合预期!
代码展示
public class BigDecimalDemo {
public static void main(String[] args) {
double d1 = 0.1;
double d2 = 0.2;
System.out.println("两个double求和:");
System.out.println(d1+d2);
System.out.println();
String s1 = "0.1";
String s2 = "0.2";
BigDecimal number1 = new BigDecimal(s1);
BigDecimal number2 = new BigDecimal(s2);
System.out.println("两个BigDecimal求和:");
System.out.println(number1.add(number2));
}
}
小结
- 使用BigDecimal主要解决基本数据类型运算精度不足的问题
- 当原数使用String表示时,使用构造方法创建BigDecimal对象;
- 当原数使用double表示时,使用valueOf()静态方法创建BigDecimal对象;
- 当需要进行算术运算时,必须使用BigDecimal提供的API;
- BigDecimal的API几乎包括了你所能想到的所有数值操作:
- 你可以将Bignteger转换成任何基本数据类型,但可能丢失精度。
- 在转换之前,应先明确是否可能丢失精度
- 你不一定需要将结果转换为数值型,使用字符串也可以用于显示或存储
其他文章
关于java中的BigInteger