float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用 java.math.BigDecimal。
而且使用BigDecimal类也可以进行大数的操作。
方法 | 类型 | 描述 |
---|---|---|
public BigDecimal(double val) | 构造 | 将double表示形式转换为BigDecimal |
public BigDecimal(int val) | 构造 | 将int表示形式转换为BigDecimal |
public BigDecimal(String val) | 构造 | 将字符串表示形式转换为BigDecimal |
public BigDecimal add(BigDecimal augend) | 普通 | 加法 |
public BigDecimal subtract(BigDecimal subtrahend) | 普通 | 减法 |
public BigDecimal multiply(BigDecimal multiplicand) | 普通 | 乘法 |
public BigDecimal divide(BigDecimal divisor) | 普通 | 除法 |
一、 BigDecimal的计算
金额的计算BigDecimal类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
double d = 9.84 ;
double d2 = 1.22 ;
//注意需要使用BigDecimal(String val)构造方法
BigDecimal bigDecimal = new BigDecimal(Double.toString(d));
BigDecimal bigDecimal2 = new BigDecimal(Double.toString(d2));
//加法
BigDecimal bigDecimalAdd = bigDecimal.add(bigDecimal2);
double add = bigDecimalAdd.doubleValue();
//减法
BigDecimal bigDecimalSubtract = bigDecimal.subtract(bigDecimal2);
double subtract = bigDecimalSubtract.doubleValue();
//乘法
BigDecimal bigDecimalMultiply = bigDecimal.multiply(bigDecimal2);
double multiply = bigDecimalMultiply.doubleValue();
//除法
int scale = 2 ; //保留2位小数
BigDecimal bigDecimalDivide = bigDecimal.divide(bigDecimal2, scale, BigDecimal.ROUND_HALF_UP);
double divide = bigDecimalDivide.doubleValue();
//格式化
double format = 12343171.6 ;
//获取常规数值格式
NumberFormat number = NumberFormat.getNumberInstance();
String str = number.format(format); //12,343,171.6
//获取整数数值格式
NumberFormat integer = NumberFormat.getIntegerInstance();
str = integer.format(format); //如果带小数会四舍五入到整数12,343,172
//获取货币数值格式
NumberFormat currency = NumberFormat.getCurrencyInstance();
currency.setMinimumFractionDigits( 2 ); //设置数的小数部分所允许的最小位数(如果不足后面补0)
currency.setMaximumFractionDigits( 4 ); //设置数的小数部分所允许的最大位数(如果超过会四舍五入)
str = currency.format(format); //¥12,343,171.60
//获取显示百分比的格式
NumberFormat percent = NumberFormat.getPercentInstance();
percent.setMinimumFractionDigits( 2 ); //设置数的小数部分所允许的最小位数(如果不足后面补0)
percent.setMaximumFractionDigits( 3 ); //设置数的小数部分所允许的最大位数(如果超过会四舍五入)
str = percent.format(format); //1,234,317,160.00%
|
二、典型的Double类型的数值运算
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
/**
* double的计算不精确,会有类似0.0000000000000002的误差,正确的方法是使用BigDecimal或者用整型
* 整型地方法适合于货币精度已知的情况,比如12.11+1.10转成1211+110计算,最后再/100即可
* 以下是摘抄的BigDecimal方法:
*/
public class DoubleUtil implements Serializable {
private static final long serialVersionUID = -3345205828566485102L;
// 默认除法运算精度
private static final Integer DEF_DIV_SCALE = 2 ;
/**
* 提供精确的加法运算。
*
* @param value1 被加数
* @param value2 加数
* @return 两个参数的和
*/
public static Double add(Double value1, Double value2) {
BigDecimal b1 = new BigDecimal(Double.toString(value1));
BigDecimal b2 = new BigDecimal(Double.toString(value2));
return b1.add(b2).doubleValue();
}
/**
* 提供精确的减法运算。
*
* @param value1 被减数
* @param value2 减数
* @return 两个参数的差
*/
public static double sub(Double value1, Double value2) {
BigDecimal b1 = new BigDecimal(Double.toString(value1));
BigDecimal b2 = new BigDecimal(Double.toString(value2));
return b1.subtract(b2).doubleValue();
}
/**
* 提供精确的乘法运算。
*
* @param value1 被乘数
* @param value2 乘数
* @return 两个参数的积
*/
public static Double mul(Double value1, Double value2) {
BigDecimal b1 = new BigDecimal(Double.toString(value1));
BigDecimal b2 = new BigDecimal(Double.toString(value2));
return b1.multiply(b2).doubleValue();
}
/**
* 提供(相对)精确的除法运算,当发生除不尽的情况时, 精确到小数点以后10位,以后的数字四舍五入。
*
* @param dividend 被除数
* @param divisor 除数
* @return 两个参数的商
*/
public static Double divide(Double dividend, Double divisor) {
return divide(dividend, divisor, DEF_DIV_SCALE);
}
/**
* 提供(相对)精确的除法运算。 当发生除不尽的情况时,由scale参数指定精度,以后的数字四舍五入。
*
* @param dividend 被除数
* @param divisor 除数
* @param scale 表示表示需要精确到小数点以后几位。
* @return 两个参数的商
*/
public static Double divide(Double dividend, Double divisor, Integer scale) {
if (scale < 0 ) {
throw new IllegalArgumentException( "The scale must be a positive integer or zero" );
}
BigDecimal b1 = new BigDecimal(Double.toString(dividend));
BigDecimal b2 = new BigDecimal(Double.toString(divisor));
return b1.divide(b2, scale,RoundingMode.HALF_UP).doubleValue();
}
/**
* 提供指定数值的(精确)小数位四舍五入处理。
*
* @param value 需要四舍五入的数字
* @param scale 小数点后保留几位
* @return 四舍五入后的结果
*/
public static double round( double value, int scale){
if (scale< 0 ){
throw new IllegalArgumentException( "The scale must be a positive integer or zero" );
}
BigDecimal b = new BigDecimal(Double.toString(value));
BigDecimal one = new BigDecimal( "1" );
return b.divide(one,scale, RoundingMode.HALF_UP).doubleValue();
}
}
|
补充:Java存储金额解决方案BigDecimal
使用BigDecimal来存储金额数据,数据库中使用decimal类型,长度18,小数点2。
在JPA中创建时如下:
1
2
|
@Column (columnDefinition= "decimal(18,2)" )
private BigDecimal price; //商品价格
|
在数据库中创建时如下:
常用构造器:
BigDecimal(double) 创建一个具有参数所指定双精度值的对象
BigDecimal(long) 创建一个具有参数所指定长整数值的对象
BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象
常用方法:加减乘除
add(BigDecimal) BigDecimal对象中的值相加,返回BigDecimal对象
subtract(BigDecimal) BigDecimal对象中的值相减,返回BigDecimal对象
multiply(BigDecimal) BigDecimal对象中的值相乘,返回BigDecimal对象
divide(BigDecimal) BigDecimal对象中的值相除,返回BigDecimal对象
常用方法:数据转换
toString() 将BigDecimal对象中的值转换成字符串
doubleValue() 将BigDecimal对象中的值转换成双精度数
floatValue() 将BigDecimal对象中的值转换成单精度数
longValue() 将BigDecimal对象中的值转换成长整数
intValue() 将BigDecimal对象中的值转换成整数
以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。如有错误或未考虑完全的地方,望不吝赐教。
原文链接:https://mailiang.blog.csdn.net/article/details/87898547