Is there a way to use DecimalFormat (or some other standard formatter) to format numbers like this:
1,000,000 => 1.00M
1,234,567 => 1.23M
1,234,567,890 => 1234.57M
Basically dividing some number by 1 million, keeping 2 decimal places, and slapping an 'M' on the end. I've thought about creating a new subclass of NumberFormat but it looks trickier than I imagined.
I'm writing an API that has a format method that looks like this:
public String format(double value, Unit unit); // Unit is an enum
Internally, I'm mapping Unit objects to NumberFormatters. The implementation is something like this:
public String format(double value, Unit unit)
{
NumberFormatter formatter = formatters.get(unit);
return formatter.format(value);
}
Note that because of this, I can't expect the client to divide by 1 million, and I can't just use String.format() without wrapping it in a NumberFormatter.
String.format("%.2fM", theNumber/ 1000000.0);
For more information see the String.format javadocs.
Note that if you have a BigDecimal
, you can use the movePointLeft
method:
new DecimalFormat("#.00").format(value.movePointLeft(6));
Here's a subclass of NumberFormat that I whipped up. It looks like it does the job but I'm not entirely sure it's the best way:
private static final NumberFormat MILLIONS = new NumberFormat()
{
private NumberFormat LOCAL_REAL = new DecimalFormat("#,##0.00M");
public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos)
{
double millions = number / 1000000D;
if(millions > 0.1) LOCAL_REAL.format(millions, toAppendTo, pos);
return toAppendTo;
}
public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos)
{
return format((double) number, toAppendTo, pos);
}
public Number parse(String source, ParsePosition parsePosition)
{
throw new UnsupportedOperationException("Not implemented...");
}
};
Why not simply?
DecimalFormat df = new DecimalFormat("0.00M");
System.out.println(df.format(n / 1000000));
Take a look at ChoiseFormat.
A more simplistic way would be to use a wrapper that auto divided by 1m for you.