jaava之BigDecimal
BigDecimal常见异常
除法的时候出现异常
1 | java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result |
原因分析:
通过BigDecimal的divide方法进行除法时当不整除,出现无限循环小数时,就会抛异常:java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
解决方法:
divide方法设置精确的小数点,如:divide(xxxxx,2)
1、总结
在需要精确的小数计算时再使用BigDecimal,BigDecimal的性能比double和float差,在处理庞大,复杂的运算时尤为明显。故一般精度的计算没必要使用BigDecimal。 尽量使用参数类型为String的构造函数。
BigDecimal都是不可变的(immutable)的, 在进行每一次四则运算时,都会产生一个新的对象 ,所以在做加减乘除运算时要记得要保存操作后的值。
2、工具类推荐
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290package
com.vivo.ars.util;
import
java.math.BigDecimal;
/**
* 用于高精确处理常用的数学运算
*/
public
class
ArithmeticUtils {
//默认除法运算精度
private
static
final
int
DEF_DIV_SCALE =
10
;
/**
* 提供精确的加法运算
*
* @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
BigDecimal add(String v1, String v2) {
BigDecimal b1 =
new
BigDecimal(v1);
BigDecimal b2 =
new
BigDecimal(v2);
return
b1.add(b2);
}
/**
* 提供精确的加法运算
*
* @param v1 被加数
* @param v2 加数
* @param scale 保留scale 位小数
* @return 两个参数的和
*/
public
static
String add(String v1, String v2,
int
scale) {
if
(scale <
0
) {
throw
new
IllegalArgumentException(
"The scale must be a positive integer or zero"
);
}
BigDecimal b1 =
new
BigDecimal(v1);
BigDecimal b2 =
new
BigDecimal(v2);
return
b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
}
/**
* 提供精确的减法运算
*
* @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
BigDecimal sub(String v1, String v2) {
BigDecimal b1 =
new
BigDecimal(v1);
BigDecimal b2 =
new
BigDecimal(v2);
return
b1.subtract(b2);
}
/**
* 提供精确的减法运算
*
* @param v1 被减数
* @param v2 减数
* @param scale 保留scale 位小数
* @return 两个参数的差
*/
public
static
String sub(String v1, String v2,
int
scale) {
if
(scale <
0
) {
throw
new
IllegalArgumentException(
"The scale must be a positive integer or zero"
);
}
BigDecimal b1 =
new
BigDecimal(v1);
BigDecimal b2 =
new
BigDecimal(v2);
return
b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
}
/**
* 提供精确的乘法运算
*
* @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();
}
/**
* 提供精确的乘法运算
*
* @param v1 被乘数
* @param v2 乘数
* @return 两个参数的积
*/
public
static
BigDecimal mul(String v1, String v2) {
BigDecimal b1 =
new
BigDecimal(v1);
BigDecimal b2 =
new
BigDecimal(v2);
return
b1.multiply(b2);
}
/**
* 提供精确的乘法运算
*
* @param v1 被乘数
* @param v2 乘数
* @param scale 保留scale 位小数
* @return 两个参数的积
*/
public
static
double
mul(
double
v1,
double
v2,
int
scale) {
BigDecimal b1 =
new
BigDecimal(Double.toString(v1));
BigDecimal b2 =
new
BigDecimal(Double.toString(v2));
return
round(b1.multiply(b2).doubleValue(), scale);
}
/**
* 提供精确的乘法运算
*
* @param v1 被乘数
* @param v2 乘数
* @param scale 保留scale 位小数
* @return 两个参数的积
*/
public
static
String mul(String v1, String v2,
int
scale) {
if
(scale <
0
) {
throw
new
IllegalArgumentException(
"The scale must be a positive integer or zero"
);
}
BigDecimal b1 =
new
BigDecimal(v1);
BigDecimal b2 =
new
BigDecimal(v2);
return
b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
}
/**
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
* 小数点以后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();
}
/**
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
* 定精度,以后的数字四舍五入
*
* @param v1 被除数
* @param v2 除数
* @param scale 表示需要精确到小数点以后几位
* @return 两个参数的商
*/
public
static
String div(String v1, String v2,
int
scale) {
if
(scale <
0
) {
throw
new
IllegalArgumentException(
"The scale must be a positive integer or zero"
);
}
BigDecimal b1 =
new
BigDecimal(v1);
BigDecimal b2 =
new
BigDecimal(v1);
return
b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString();
}
/**
* 提供精确的小数位四舍五入处理
*
* @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));
return
b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供精确的小数位四舍五入处理
*
* @param v 需要四舍五入的数字
* @param scale 小数点后保留几位
* @return 四舍五入后的结果
*/
public
static
String round(String v,
int
scale) {
if
(scale <
0
) {
throw
new
IllegalArgumentException(
"The scale must be a positive integer or zero"
);
}
BigDecimal b =
new
BigDecimal(v);
return
b.setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
}
/**
* 取余数
*
* @param v1 被除数
* @param v2 除数
* @param scale 小数点后保留几位
* @return 余数
*/
public
static
String remainder(String v1, String v2,
int
scale) {
if
(scale <
0
) {
throw
new
IllegalArgumentException(
"The scale must be a positive integer or zero"
);
}
BigDecimal b1 =
new
BigDecimal(v1);
BigDecimal b2 =
new
BigDecimal(v2);
return
b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
}
/**
* 取余数 BigDecimal
*
* @param v1 被除数
* @param v2 除数
* @param scale 小数点后保留几位
* @return 余数
*/
public
static
BigDecimal remainder(BigDecimal v1, BigDecimal v2,
int
scale) {
if
(scale <
0
) {
throw
new
IllegalArgumentException(
"The scale must be a positive integer or zero"
);
}
return
v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP);
}
/**
* 比较大小
*
* @param v1 被比较数
* @param v2 比较数
* @return 如果v1 大于v2 则 返回true 否则false
*/
public
static
boolean
compare(String v1, String v2) {
BigDecimal b1 =
new
BigDecimal(v1);
BigDecimal b2 =
new
BigDecimal(v2);
int
bj = b1.compareTo(b2);
boolean
res;
if
(bj >
0
)
res =
true
;
else
res =
false
;
return
res;
}
}
来源:cnblogs.com/zhangyinhua/p/11545305.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」