[ 
https://issues.apache.org/jira/browse/FINERACT-2988?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18132435#comment-18132435
 ] 

LeeYoonMyeong commented on FINERACT-2988:
-----------------------------------------

Fixed by https://github.com/apache/fineract/pull/6731 (merged). Could a 
committer please resolve this issue with Fix Version 1.17.0? I don't have 
permission to transition it.

> Tax split uses double arithmetic and can be off by one minor unit at rounding 
> boundaries
> ----------------------------------------------------------------------------------------
>
>                 Key: FINERACT-2988
>                 URL: https://issues.apache.org/jira/browse/FINERACT-2988
>             Project: Apache Fineract
>          Issue Type: Bug
>          Components: Savings
>            Reporter: LeeYoonMyeong
>            Priority: Major
>
> {\{TaxUtils.splitTax}} and \{{TaxUtils.splitTaxData}} compute each tax 
> component as
> {code:java}
> double tax = amount.doubleValue() * percentage.doubleValue() / 100.0;
> BigDecimal.valueOf(tax).setScale(scale, MoneyHelper.getRoundingMode());
> {code}
> When the exact product lies on a rounding boundary, the binary double is 
> slightly below it, so the configured rounding mode is applied to the wrong 
> side. These methods are used for withholding tax on savings interest posting 
> (\{{SavingsAccount}}, \{{SavingsAccountInterestPostingServiceImpl}}) and for 
> charge tax (\{{ChargeTaxApplicationServiceImpl}}).
> Examples (exact value -> expected -> current):
> * 4.10 at 15 %, scale 2, HALF_EVEN: 0.615 -> 0.62 -> *0.61*
> * 5250 at 1.4 %, scale 0, HALF_EVEN: 73.5 -> 74 -> *73*
> * 5500 at 1.4 %, scale 0, DOWN: 77 -> 77 -> *76*
> I scanned whole amounts 1..1,000,000 at 1.4 % (scale 0) and found 187 
> differing amounts under HALF_EVEN and 374 under HALF_UP. Amounts 
> 0.01..10,000.00 at 15 % (scale 2) gave 658 differing amounts under HALF_EVEN. 
> Rates such as 10 %, 14 % and 16 % gave no differences in these ranges. That 
> is why the existing tests (e.g. 1000 at 16 %) pass.
> *Proposed fix:* compute the product exactly with BigDecimal and round once: 
> \{{amount.multiply(percentage).movePointLeft(2).setScale(scale, 
> MoneyHelper.getRoundingMode())}}. Results change only where the exact value 
> is on a rounding boundary. I have a patch with unit tests ready and would 
> like to work on this issue.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to