Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Money (USD) calculations not rounding properly #387

Open
arnaldop opened this issue Feb 24, 2023 · 1 comment
Open

Money (USD) calculations not rounding properly #387

arnaldop opened this issue Feb 24, 2023 · 1 comment
Labels

Comments

@arnaldop
Copy link

The method below returns true for "USD 0.00".

@Override
public boolean warn() {
    return hasDisplayOptions(ExportDisplayOptions.ALWAYS_WARN)
           || value == null
           || value.isNegative()
            //               || is(new BigDecimal(value.getNumber().doubleValue())
            //                             .setScale(2, RoundingMode.HALF_EVEN))
            //                       .isNegative()
            ;
}

All monetary amounts enter my application through code like this:

public static final CurrencyUnit DOLLAR = Monetary.getCurrency(Locale.US);
public static MonetaryAmount of(@NonNull final String value) {
    return Money.of(new BigDecimal(value), DOLLAR);
}
public static MonetaryAmount of(final double value) {
    return Money.of(value, DOLLAR);
}
public static MonetaryAmount of(@NonNull final BigDecimal value) {
    return Money.of(value, DOLLAR);
}

As the screenshot below shows, after a number of calculations, my Money object that should only have 2 decimal places still holds 4, and it considers the full number when evaluating isNegative().

image

My understanding was that by using Moneta with USD, I would be guaranteed that monetary amounts would round up to the 2nd decimal place to match the US Dollar. Am I misusing the library or is this a bug?

Note: lots of adding, subtracting, and applying percentages is done to these numbers. I can try to come up with a small example, but I figured I'd ask here if this was a known issue. I saw #384, #304 and #277, but I'm using Money, not FastMoney nor RoundedMoney.

Using version 1.4.2.

@keilw keilw added the analysis label Jan 24, 2024
@kewne
Copy link
Contributor

kewne commented Apr 20, 2024

As far as I can tell from looking at the spec, there is nothing that guarantees or even suggests that monetary amounts are implicitly rounded while performing calculations.

To me, this makes sense because it would otherwise make it impossible to sum amounts that round to zero.

If implicit rounding after each operation is required, RoundedMoney should be used.
Otherwise, it is up to client code to perform the rounding explicitly.

In this case, I agree it is misleading to have toString perform rounding, thus misrepresenting the underlying amount.
I think it would be an improvement to change it to something like number.toString + ' ' + currency.getCurrencyCode that would make the issue obvious but, at this point, it would be a breaking change despite not being in the spec.

In other words, the current behavior with regards to rounding seems to be correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants