BigDecimal通过setScale设置小数位数发生ArithmeticException
来源:互联网 发布:网络动作游戏排行榜 编辑:程序博客网 时间:2024/06/06 12:42
一、前言
通常进行数值计算时,我们会先将double或float等转为BigDecimal再处理,然后对计算结果通过setScale方法取指定的小数位;但是在这里有时会遇到java.lang.ArithmeticException: Rounding necessary,下面我们会对此问题进行演示和说明。
二、代码示例
1. 这里以double转BigDecimal后获取不同小数位值来举例说明,具体如下:
public
static
void
main(String[] args) {
double
d =
10.0000000001
;
String s =
"10.0000000001"
;
BigDecimal newBigDecimal =
new
BigDecimal(d);
BigDecimal newStringBigDecimal =
new
BigDecimal(s);
BigDecimal valueOfBigDecimal = BigDecimal.valueOf(d);
// newBigDecimal===================================
System.out.println(
"newBigDecimal's scale:"
+ newBigDecimal.scale());
try
{
System.out.println(
"newBigDecimal setScale(50):"
+ newBigDecimal.setScale(
50
));
}
catch
(Exception e) {
System.out.println(
"newBigDecimal setScale(50):"
+ e);
}
try
{
System.out.println(
"newBigDecimal setScale(49):"
+ newBigDecimal.setScale(
49
));
}
catch
(Exception e) {
System.out.println(
"newBigDecimal setScale(49):"
+ e);
}
try
{
System.out.println(
"newBigDecimal setScale(48):"
+ newBigDecimal.setScale(
48
));
}
catch
(Exception e) {
System.out.println(
"newBigDecimal setScale(48):"
+ e);
System.out.println(
"newBigDecimal setScale(48, RoundingMode.HALF_UP):"
+ newBigDecimal.setScale(
48
, RoundingMode.HALF_UP));
}
// valueOfBigDecimal======================================
System.out.println(
"valueOfBigDecimal's scale:"
+ valueOfBigDecimal.scale());
try
{
System.out.println(
"valueOfBigDecimal setScale(50):"
+ valueOfBigDecimal.setScale(
50
));
}
catch
(Exception e) {
System.out.println(
"valueOfBigDecimal setScale(50):"
+ e);
}
try
{
System.out.println(
"valueOfBigDecimal setScale(49):"
+ valueOfBigDecimal.setScale(
49
));
}
catch
(Exception e) {
System.out.println(
"valueOfBigDecimal setScale(49):"
+ e);
}
try
{
System.out.println(
"valueOfBigDecimal setScale(48):"
+ valueOfBigDecimal.setScale(
48
));
}
catch
(Exception e) {
System.out.println(
"valueOfBigDecimal setScale(48):"
+ e);
System.out.println(
"valueOfBigDecimal setScale(48, RoundingMode.HALF_UP):"
+ valueOfBigDecimal.setScale(
48
, RoundingMode.HALF_UP));
}
// newStringBigDecimal======================================
System.out.println(
"newStringBigDecimal's scale:"
+ newStringBigDecimal.scale());
try
{
System.out.println(
"newStringBigDecimal setScale(50):"
+ newStringBigDecimal.setScale(
50
));
}
catch
(Exception e) {
System.out.println(
"newStringBigDecimal setScale(50):"
+ e);
}
try
{
System.out.println(
"newStringBigDecimal setScale(49):"
+ newStringBigDecimal.setScale(
49
));
}
catch
(Exception e) {
System.out.println(
"newStringBigDecimal setScale(49):"
+ e);
}
try
{
System.out.println(
"newStringBigDecimal setScale(48):"
+ newStringBigDecimal.setScale(
48
));
}
catch
(Exception e) {
System.out.println(
"newStringBigDecimal setScale(48):"
+ e);
System.out.println(
"newStringBigDecimal setScale(48, RoundingMode.HALF_UP):"
+ newStringBigDecimal.setScale(
48
, RoundingMode.HALF_UP));
}
d =
10.01
;
s =
"10.01"
;
newBigDecimal =
new
BigDecimal(d);
valueOfBigDecimal = BigDecimal.valueOf(d);
newStringBigDecimal =
new
BigDecimal(s);
// newBigDecimal==========================================
System.out.println(
"newBigDecimal's scale:"
+ newBigDecimal.scale());
try
{
System.out.println(
"newBigDecimal setScale(3):"
+ newBigDecimal.setScale(
3
));
}
catch
(Exception e) {
System.out.println(
"newBigDecimal setScale(3):"
+ e);
System.out.println(
"newBigDecimal setScale(3, RoundingMode.HALF_UP):"
+ newBigDecimal.setScale(
3
, RoundingMode.HALF_UP));
}
try
{
System.out.println(
"newBigDecimal setScale(2):"
+ newBigDecimal.setScale(
2
));
}
catch
(Exception e) {
System.out.println(
"newBigDecimal setScale(2):"
+ e);
System.out.println(
"newBigDecimal setScale(2, RoundingMode.HALF_UP):"
+ newBigDecimal.setScale(
2
, RoundingMode.HALF_UP));
}
try
{
System.out.println(
"newBigDecimal setScale(1):"
+ newBigDecimal.setScale(
1
));
}
catch
(Exception e) {
System.out.println(
"newBigDecimal setScale(1):"
+ e);
System.out.println(
"newBigDecimal setScale(1, RoundingMode.HALF_UP):"
+ newBigDecimal.setScale(
1
, RoundingMode.HALF_UP));
}
// valueOfBigDecimal======================================
System.out.println(
"valueOfBigDecimal's scale:"
+ valueOfBigDecimal.scale());
try
{
System.out.println(
"valueOfBigDecimal setScale(3):"
+ valueOfBigDecimal.setScale(
3
));
}
catch
(Exception e) {
System.out.println(
"valueOfBigDecimal setScale(3):"
+ e);
}
try
{
System.out.println(
"valueOfBigDecimal setScale(2):"
+ valueOfBigDecimal.setScale(
2
));
}
catch
(Exception e) {
System.out.println(
"valueOfBigDecimal setScale(2):"
+ e);
}
try
{
System.out.println(
"valueOfBigDecimal setScale(1):"
+ valueOfBigDecimal.setScale(
1
));
}
catch
(Exception e) {
System.out.println(
"valueOfBigDecimal setScale(1):"
+ e);
System.out.println(
"valueOfBigDecimal setScale(1, RoundingMode.HALF_UP):"
+ valueOfBigDecimal.setScale(
1
, RoundingMode.HALF_UP));
}
//
// newStringBigDecimal======================================
System.out.println(
"newStringBigDecimal's scale:"
+ newStringBigDecimal.scale());
try
{
System.out.println(
"newStringBigDecimal setScale(3):"
+ newStringBigDecimal.setScale(
3
));
}
catch
(Exception e) {
System.out.println(
"newStringBigDecimal setScale(3):"
+ e);
}
try
{
System.out.println(
"newStringBigDecimal setScale(2):"
+ newStringBigDecimal.setScale(
2
));
}
catch
(Exception e) {
System.out.println(
"newStringBigDecimal setScale(2):"
+ e);
}
try
{
System.out.println(
"newStringBigDecimal setScale(1):"
+ newStringBigDecimal.setScale(
1
));
}
catch
(Exception e) {
System.out.println(
"newStringBigDecimal setScale(1):"
+ e);
System.out.println(
"newStringBigDecimal setScale(1, RoundingMode.HALF_UP):"
+ newStringBigDecimal.setScale(
1
, RoundingMode.HALF_UP));
}
}
运算结果如下:
newBigDecimal's scale:
49
newBigDecimal setScale(
50
):
10.00000000010000000827403709990903735160827636718750
newBigDecimal setScale(
49
):
10.0000000001000000082740370999090373516082763671875
newBigDecimal setScale(
48
):java.lang.ArithmeticException: Rounding necessary
newBigDecimal setScale(
48
, RoundingMode.HALF_UP):
10.000000000100000008274037099909037351608276367188
valueOfBigDecimal's scale:
10
valueOfBigDecimal setScale(
50
):
10.00000000010000000000000000000000000000000000000000
valueOfBigDecimal setScale(
49
):
10.0000000001000000000000000000000000000000000000000
valueOfBigDecimal setScale(
48
):
10.000000000100000000000000000000000000000000000000
newStringBigDecimal's scale:
10
newStringBigDecimal setScale(
50
):
10.00000000010000000000000000000000000000000000000000
newStringBigDecimal setScale(
49
):
10.0000000001000000000000000000000000000000000000000
newStringBigDecimal setScale(
48
):
10.000000000100000000000000000000000000000000000000
newBigDecimal's scale:
49
newBigDecimal's value:
10.0099999999999997868371792719699442386627197265625
newBigDecimal setScale(
3
):java.lang.ArithmeticException: Rounding necessary
newBigDecimal setScale(
3
, RoundingMode.HALF_UP):
10.010
newBigDecimal setScale(
2
):java.lang.ArithmeticException: Rounding necessary
newBigDecimal setScale(
2
, RoundingMode.HALF_UP):
10.01
newBigDecimal setScale(
1
):java.lang.ArithmeticException: Rounding necessary
newBigDecimal setScale(
1
, RoundingMode.HALF_UP):
10.0
valueOfBigDecimal's scale:
2
valueOfBigDecimal setScale(
3
):
10.010
valueOfBigDecimal setScale(
2
):
10.01
valueOfBigDecimal setScale(
1
):java.lang.ArithmeticException: Rounding necessary
valueOfBigDecimal setScale(
1
, RoundingMode.HALF_UP):
10.0
newStringBigDecimal's scale:
2
newStringBigDecimal setScale(
3
):
10.010
newStringBigDecimal setScale(
2
):
10.01
newStringBigDecimal setScale(
1
):java.lang.ArithmeticException: Rounding necessary
newStringBigDecimal setScale(
1
, RoundingMode.HALF_UP):
10.0
2. 结果分析:
通过运行结果我们会发现两种情况:
①通过new直接将double作为参数传入得到的值输出后并不等于原double值,传入string或valueOf方法得到的结果等于原值;事实上查看Java文档会发现有三种方式将double转为BigDecimal:1. new BigDecimal(double d); 2. new BigDecimal(String s);3.BigDecimal.valueOf(double d) ; 第一种是double的二进制形式的结果,所以BigDecimal的值并不一定为其原值,如上代码所示:10.0000000001转换后为10.0000000001000000082740370999090373516082763671875 ,共有49位小数(不同机器结果会不同),10.01转换后为10.0099999999999997868371792719699442386627197265625,第二种和第三种结果相同,仍然为原值,因为第三种相当于先将double转为String(Double.toString(double))。
②同时我们会发现,设置结果小数位数小于当前位数时,如果未设置进位方式会抛出异常:java.lang.ArithmeticException: Rounding necessary,提示我们进位方式必须,当我们设置四舍五入后即可,其他方式可查看RoundingMode枚举类。
三、结论:
通过上述分析,我们可以看出当对BigDecimal的值进位时需指定进位方式,否则会发生java.lang.ArithmeticException: Rounding necessary。
- BigDecimal通过setScale设置小数位数发生ArithmeticException
- BigDecimal设置小数位数
- BigDecimal.setScale 处理java小数用法
- Hibernate设置映射BigDecimal类型的小数位数
- 关于BigDecimal截取小数位数
- BigDecimal.setScale
- BigDecimal.setScale
- BigDecimal.setScale()
- BigDecimal.setScale()
- BigDecimal类setScale方法问题:算数异常,精确度丢失-ArithmeticException: Rounding necessary
- BigDecimal 小数点位数设置
- BigDecimal设置小数点位数
- 利用bigDecimal直接截取小数位数
- java中使用BigDecimal保留小数位数
- 给BigDecimal设置小数点位数
- BigDecimal.setScale()方法
- BigDecimal.setScale用法总结
- Poi excel设置小数位数
- android实现和web一样的阴影效果
- xamarin.forms 网络连接检测及网络状态判断案例
- java 中泛型
- linux makefile 速查
- 常用的testbench和matlab代码之读取和写入文本代码
- BigDecimal通过setScale设置小数位数发生ArithmeticException
- IOCP简单示例
- LoadRunner关联
- 添加了索引但不被使用的几种常见可能
- iconfont字体图标的使用
- 初识kotlin,实现一个简单的列表
- CentOS 安装Oracle 11gR2步骤和一些安装过程中出现的错误(整理)
- java map的遍历
- python入门推荐资料