仅当小数重复时才设置 BigDecimal 精度
Set BigDecimal precision only if decimals repeating
我知道我可以使用BigDecimal.divide()
方法来设置固定精度:
BigDecimal a1 = new BigDecimal(1);
BigDecimal a2 = new BigDecimal(3);
BigDecimal division = a1.divide(a2,5,1); //equals 0.33333
但如果除法结果是准确的:
BigDecimal a1 = new BigDecimal(1);
BigDecimal a2 = new BigDecimal(4);
BigDecimal division = a1.divide(a2,5,1); //equals 0.25000
如何设置除法结果,如果除法以精确结果结束,它只会给出 0.25 而不是 0.25000 的输出?
我也尝试通过以下方式不指定精度:
BigDecimal division = a1.divide(a2);
它在做 1/4
时成功地给出了结果 0.25
,但是当它像 1/3
或 2/3
这样的除法时它会导致运行时 ArithmeticException
.
a1
和 a2
从用户输入实例化。
有什么办法可以解决吗?
您得到 ArithmeticException
,如 BigDecimal.divide(BigDecimal)
- "if the exact quotient does not have a terminating decimal expansion" because to properly represent the result of 1/3
would take infinite memory. By using BigDecimal.divide(BigDecimal,int,RoundingMode)
中所述,您明确设置了您可以容忍的精度,这意味着任何除法都可以在内存中进行近似计算。
为了保持一致性,此版本的除法始终将比例设置为您指定的比例,即使该值可以用较低的精度准确表示。如果没有,您将很难推断出使用该结果的任何未来计算的精确度。
要降低精度,请使用 .stripTrailingZeros()
;这有效地将规模缩小到尽可能小。尽可能晚(即在打印之前)执行此操作以保持我上面提到的一致性。
如果您想很好地显示这些值,您可能还需要 .toPlainString()
,因为 .stripTrailingZeros()
本身会将 100
显示为 1E+2
。
我知道我可以使用BigDecimal.divide()
方法来设置固定精度:
BigDecimal a1 = new BigDecimal(1);
BigDecimal a2 = new BigDecimal(3);
BigDecimal division = a1.divide(a2,5,1); //equals 0.33333
但如果除法结果是准确的:
BigDecimal a1 = new BigDecimal(1);
BigDecimal a2 = new BigDecimal(4);
BigDecimal division = a1.divide(a2,5,1); //equals 0.25000
如何设置除法结果,如果除法以精确结果结束,它只会给出 0.25 而不是 0.25000 的输出?
我也尝试通过以下方式不指定精度:
BigDecimal division = a1.divide(a2);
它在做 1/4
时成功地给出了结果 0.25
,但是当它像 1/3
或 2/3
这样的除法时它会导致运行时 ArithmeticException
.
a1
和 a2
从用户输入实例化。
有什么办法可以解决吗?
您得到 ArithmeticException
,如 BigDecimal.divide(BigDecimal)
- "if the exact quotient does not have a terminating decimal expansion" because to properly represent the result of 1/3
would take infinite memory. By using BigDecimal.divide(BigDecimal,int,RoundingMode)
中所述,您明确设置了您可以容忍的精度,这意味着任何除法都可以在内存中进行近似计算。
为了保持一致性,此版本的除法始终将比例设置为您指定的比例,即使该值可以用较低的精度准确表示。如果没有,您将很难推断出使用该结果的任何未来计算的精确度。
要降低精度,请使用 .stripTrailingZeros()
;这有效地将规模缩小到尽可能小。尽可能晚(即在打印之前)执行此操作以保持我上面提到的一致性。
如果您想很好地显示这些值,您可能还需要 .toPlainString()
,因为 .stripTrailingZeros()
本身会将 100
显示为 1E+2
。