这将导致ArithmeticException:http://ideone.com/RXeZw
提供一个刻度和舍入模式会给我错误的结果。这个例子应该输出50.03%。如何正确地解决这一问题?
为了便于参考,下面是代码:
BigDecimal priceDiff = BigDecimal.ONE
.subtract(new BigDecimal(9.99)
.divide(new BigDecimal(19.99)))
.multiply(new BigDecimal(100));
System.out.println(priceDiff.toPlainString());发布于 2012-08-29 12:39:01
如果不能准确表示结果,BigDecimal.divide(BigDecimal divisor)将抛出一个ArithmeticException。
您必须使用提供一个MathContext或RoundingMode来告诉您如何处理这个问题。例如:
public class Test {
public static void main(String[] args) throws java.lang.Exception {
BigDecimal priceDiff = BigDecimal.ONE.subtract(new BigDecimal("9.99").divide(new BigDecimal("19.99"), MathContext.DECIMAL128))
.multiply(new BigDecimal(100));
System.out.println(priceDiff.toPlainString());
}
}作品和版画
50.0250125062531265632816408204102100另外,请注意使用构造函数来避免使用BigDecimal文本创建double时出现的问题。
发布于 2012-08-29 12:39:15
您应该使用一个MathContext作为您的除法,作为一个无限数量的小数:
BigDecimal priceDiff = BigDecimal.ONE
.subtract(new BigDecimal(9.99)
.divide(new BigDecimal(19.99), new MathContext(10, RoundingMode.UP)))
.multiply(new BigDecimal(100));
System.out.println(priceDiff.toPlainString());不过,印了50.025.
这将打印49.98:
BigDecimal priceDiff = new BigDecimal(9.99)
.divide(new BigDecimal(19.99), new MathContext(10, RoundingMode.UP))
.multiply(new BigDecimal(100), new MathContext(4, RoundingMode.UP));
System.out.println(priceDiff.toPlainString());发布于 2012-08-29 12:44:15
来自Javadoc
在除法的情况下,精确商可以有一个无限长的十进制展开;例如,1除以3。如果商有一个不终止的十进制展开,并且指定了返回精确结果的运算,则抛出一个ArithmeticException。
解决方案是向部门提供一个MathContext,例如MathContext.DECIMAL128。如果您希望按照传统的方法进行舍入(四舍五入而不是最接近的偶数),请使用MathContext(int precision)。
您还应该使用String参数而不是double参数来创建您的double参数,因为后者会导致精度的下降。
https://stackoverflow.com/questions/12178053
复制相似问题