2012-04-05 46 views
3

我们来看看下面的Java代码片段。为什么Java中两个BigDecimal数字的划分会抛出ArithmeticException?

package division; 

import java.math.BigDecimal; 

final public class Main 
{ 
    public static void main(String[] args) 
    { 
     BigDecimal a = new BigDecimal(2); 
     BigDecimal b = new BigDecimal(3); 

     System.out.println(a.multiply(b)); 
     System.out.println(a.add(b)); 
     System.out.println(b.subtract(a)); 
     System.out.println(a.divide(b)); 
    } 
} 

在上面的代码片段中,除最后一个(除法)之外的所有操作都成功执行。试图在Java中划分两个BigDecimal数字会引发java.lang.ArithmeticException。为什么?这个问题的解决方案是什么?

+2

它似乎是这样的:http://stackoverflow.com/questions/2749375/arithmeticexception-thrown-during-bigdecimal-divide – dexametason 2012-04-05 17:10:59

回答

9

BigDecimal#divide(BigDecimal) documentation

...如果准确的商值不能表示(因为它具有非终止十进制扩展),则抛出ArithmeticException。

在您的具体情况“2/3”具有非十进制扩展(0.6666 ...),所以你必须使用divide()一种形式,这需要规模和/或RoundingMode来解决无限的表示。例如:

BigDecimal a = new BigDecimal(2); 
BigDecimal b = new BigDecimal(3); 
a.divide(b, 4, RoundingMode.CEILING); // => 0.6667 
a.divide(b, 4, RoundingMode.FLOOR); // => 0.6666 
1

如果你读了javadoc它说,它会抛出一个java.lang.ArithmeticException如果准确的商值没有十进制扩展。 2/3 = .666666666 ...并且不终止

1

返回值为(this/divisor)且首选比例为(this.scale() - divisor.scale())的BigDecimal;如果确切的商不能被表示(因为它具有非终止的十进制扩展),则抛出ArithmeticException。

2/3 = 0.666666666666666666666 ........等等,并且它不能被表示。正如JavaDoc所说,它是一个非终止的十进制扩展

2

您会得到例外,因为没有确切的表示划分结果。为了解决这个问题,你需要使用过载随着规模和舍入模式,就像这样:

System.out.println(a.divide(b, 20, RoundingMode.HALF_UP)); 

这里是your modified code on ideone

6 
5 
1 
0.66666666666666666667 
相关问题