1.异常信息摘要(详细请见文末):
java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
2.原因
Bigdecimal 做除法时,没有指定结果小数位精度和舍入模式,而除法的结果刚好是一个无限循环小数。
3.示例
4.解决
Bigdecimal.divide有几个重载方法,其中有三个参数的是最全的方法。其第一个参数的是除数,第二个参数是结果小数位值,第三个参数是舍入规则,所以我们在计算时将参数都指定就行了。三个参数的方法的源码:
public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) {
if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
throw new IllegalArgumentException("Invalid rounding mode");
if (this.intCompact != INFLATED) {
if ((divisor.intCompact != INFLATED)) {
return divide(this.intCompact, this.scale, divisor.intCompact, divisor.scale, scale, roundingMode);
} else {
return divide(this.intCompact, this.scale, divisor.intVal, divisor.scale, scale, roundingMode);
}
} else {
if ((divisor.intCompact != INFLATED)) {
return divide(this.intVal, this.scale, divisor.intCompact, divisor.scale, scale, roundingMode);
} else {
return divide(this.intVal, this.scale, divisor.intVal, divisor.scale, scale, roundingMode);
}
}
}
结果:
5.附:异常信息详细
java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. at java.math.BigDecimal.divide(BigDecimal.java:)
at com.lx.home.controller.HomeControllerTest.divideTest(HomeControllerTest.java:)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:)
at java.lang.reflect.Method.invoke(Method.java:)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$(ExecutableInvoker.java:)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$(ExecutableInvoker.java:)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$(TestMethodTestDescriptor.java:)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$(NodeTestTask.java:)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$(NodeTestTask.java:)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$(NodeTestTask.java:)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:)
at java.util.ArrayList.forEach(ArrayList.java:)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$(NodeTestTask.java:)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$(NodeTestTask.java:)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$(NodeTestTask.java:)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:)
at java.util.ArrayList.forEach(ArrayList.java:)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$(NodeTestTask.java:)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$(NodeTestTask.java:)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$(NodeTestTask.java:)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$(DefaultLauncher.java:)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:)