The built in DecimalFormat only allows you to specify number of digits to the right of the decimal place.
Because of the limitations of representing numbers as double, number formatting needs to include some level of rounding inside of it. In the general case, that rounding has to be to a number of significant digits (default case is the precision of a double) or else your formatted double will end up showing stuff like 3.5999999 instead of 3.6.
The closest solution I could find is using
new BigDecimal(double, new MathContext(14, RoundingMode.HALF_EVEN).stripTrailingZeros().toPlainString()
however, that only provides a single format. If I need to format it generally (group separator, decimal separator, limit to number of digits, padding, etc.), there is nothing in the JDK library.
Is there a general number formatting library out there that will handle rounding to significant digits properly?
Someone asked for examples. So, let's say I wanted to format to 4 significant digits, then:
0.000003599999 -> 0.0000036
4.12345 -> 4.123
1234.345 -> 1234
The general approach we would take would be to round to 14 digits since depending on the circumstances, a double can only represent around 15-17 significant digits anyway (or so I've read).
You can use the DecimalFormat class to format decimal numbers into locale-specific strings. This class allows you to control the display of leading and trailing zeros, prefixes and suffixes, grouping (thousands) separators, and the decimal separator.
Just use %. 2f as the format specifier. This will make the Java printf format a double to two decimal places.
NumberFormat is the abstract base class for all number formats. This class provides the interface for formatting and parsing numbers. NumberFormat also provides methods for determining which locales have number formats, and what their names are. NumberFormat helps you to format and parse numbers for any locale.
This adds a lot of overhead (5 MB or so), but the International Components for Unicode project has an enhanced DecimalFormat that handles significant digits nicely.
http://icu-project.org/apiref/icu4j/com/ibm/icu/text/DecimalFormat.html#sigdig
DecimalFormat formatter = new DecimalFormat();
formatter.setMaximumSignificantDigits( 4 );
System.out.println( formatter.format( hoursSinceLastAccident ) );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With