I'd like to use String.format() to format some BigDecimals as part of a string:
// Example:
String getPrice( String pattern )
{
BigDecimal price = basePrice.multiply( BigDecimal.ONE.add( vatRate ) );
BigDecimal priceInPence = price.multiply( new BigDecimal( "100" ) );
BigDecimal annualPrice = price.multiply( new BigDecimal( "365" ) );
return String.format( pattern, priceInPence, annualPrice );
}
String myPrice1 = getPrice( "Your price is %1$.3fp/day (£2$.2f/year) including VAT" );
// --> "Your price is 32.100p/day (£117.16/year) including VAT"
String myPrice2 = getPrice( "Around £%2$.0f annualy" );
// --> "Around £117 annually"
However the docs for String.format() say that any rounding of BigDecimals will be done with HALF_UP rounding, whereas I need HALF_EVEN.
I know how to manually set the scale of BigDecimals (Set specific precision of a BigDecimal) - but in this case I want to be able to use an arbitrary pattern string (including non-numeric pattern elements), so I won't know in advance what scale to use.
My question is therefore:
can I set the rounding mode used by String.format()? OR
is there another formatter or library that would format the numbers as in my example?
Really "solid" advice to add 5000 lines of dead-weight code to your project! From what I see, the Formatter will not set scale unless it is already set to what is needed. So help it out, parse the format string and set your scale:
with these numbers I get this output:
So it applies correct rounding.
can I set the rounding mode used by String.format()?
Short answer: no.
is there another formatter or library that would format the numbers as in my example?
The BigDecimal is converted internally via
new MathContext(compPrec)
or plainHALF_UP
. You can take the code ofjava.util.Formatter
of the latest (or your preferred) version Java and modify the creation of the MathContext to use HALF_EVEN. It should be 10-15minutes work. But then you need a custom method to mimicString.format
:Set the scale with the rounding mode you like, and include the values in the format string as strings, using
BigDecimal#toString()
.