简体   繁体   English

Java BigDecimal 是否需要四舍五入?

[英]Java BigDecimal is rounding necessary with addition?

I am working with BigDecimal and I know that if I divide I have to use MathContext and tell which Scale and RoundingMode to avoid ArithmeticException as described in the documentation:我正在使用BigDecimal并且我知道如果我除以我必须使用MathContext并告诉哪个ScaleRoundingMode来避免文档中描述的ArithmeticException

In the case of divide, the exact quotient could have an infinitely long decimal expansion;在除法的情况下,精确的商可以有无限长的十进制展开; for example, 1 divided by 3. If the quotient has a nonterminating decimal expansion and the operation is specified to return an exact result, an ArithmeticException is thrown.例如,1 除以 3。如果商具有非终止的十进制扩展并且指定运算返回精确结果,则抛出 ArithmeticException。

In the method I'm working on I have to sum amounts coming from our database (that are rounded at 2 decimals) with amounts coming from an external service, and I don't know the exact scaling of these amounts (probabily 3 decimals).在我正在研究的方法中,我必须将来自我们数据库的金额(四舍五入到 2 位小数)与来自外部服务的金额相加,我不知道这些金额的确切比例(可能是 3 位小数) .

My question is, can I trust BigDecimal 's add method and use it without rounding and scaling or it's a good practice to always specify the desired scale?我的问题是,我可以相信BigDecimal的 add 方法并在不舍入和缩放的情况下使用它,还是始终指定所需的比例是一个好习惯?

Is there any particular case in which addition and subtraction can raise ArithmeticException ?是否存在加法和减法可以引发ArithmeticException特殊情况?

BigDecimal.add() will throw ArithmeticException if the scale of the result does not fit into an int .如果结果的比例不适合int BigDecimal.add()将抛出ArithmeticException

A simple example is adding two numbers with the maximum and the minimum scales:一个简单的例子是将两个数字与最大和最小比例相加:

BigDecimal a = new BigDecimal(BigInteger.ONE, Integer.MIN_VALUE);
BigDecimal b = new BigDecimal(BigInteger.ONE, Integer.MAX_VALUE);
a.add(b);

If your application needs to operate at such scale then you probably have some bigger problems than worrying about arithmetic exception.如果您的应用程序需要以这样的规模运行,那么您可能会遇到比担心算术异常更大的问题。

Adding numbers without using MathContext will maintain proper scale and give you the precice result.在不使用MathContext情况下添加数字将保持适当的比例并为您提供精确的结果。 Depending on the actual values this approach can use arbitrary amount of memory to represent increasingly long numbers, and longer numbers take more time to add.根据实际值,这种方法可以使用任意数量的内存来表示越来越长的数字,而更长的数字需要更多的时间来添加。

Adding numbers without using MathContext and rouding once after the summation will give you the precice result rounded to the requested MathContext .在不使用MathContext情况下添加数字并在求和后进行一次计算将为您提供四舍五入到请求的MathContext的精确结果。 The memory and computation costs are the same as in the first case.内存和计算成本与第一种情况相同。

Using MathContext for each addition will produce a result which can differ from the presize result by an arbitrary value, but the memory and speed will be more predicatable.对每个加法使用MathContext将产生一个结果,该结果可能与 presize 结果相差任意值,但内存和速度将更加可预测。

Choosing which one of these approaches to use really depends on the nature of the task, so it is up to you to assess and chose the proper approach for each particular case.选择使用这些方法中的哪一种实际上取决于任务的性质,因此由您来评估并为每个特定案例选择正确的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM