2009-02-09 8 views
8

Gibt es eine Möglichkeit DecimalFormat (oder ein anderes Standard-Formatierungs) zu Format Zahlen wie folgt zu verwenden:Java: Format Zahl in Millionen

1.000.000 => 1,00 M

1.234.567 => 1.23m

1234567890 => 1234.57M

Grundsätzlich gewisse Zahl von 1 Million Dividieren halten 2 Dezimalstellen, und schlug ein 'M' am Ende. Ich habe darüber nachgedacht, eine neue Unterklasse von NumberFormat zu erstellen, aber es sieht komplizierter aus als ich es mir vorgestellt habe.

Ich schreibe eine API, die ein Format Methode, die wie folgt aussieht:

public String format(double value, Unit unit); // Unit is an enum 

Intern Ich bin Mapping-Einheit Objekte NumberFormatters. Die Umsetzung ist in etwa so:

public String format(double value, Unit unit) 
{ 
    NumberFormatter formatter = formatters.get(unit); 
    return formatter.format(value); 
} 

Beachten Sie, dass aus diesem Grunde, ich nicht der Kunde von 1 Million, teilen erwarten kann, und ich kann nicht nur String.format() verwenden, ohne sie in einer Verpackung NummerFormatter.

+0

Wollen Sie nur M (ega) zu handhaben, oder auch (G) iga, (T) Ära , etc? –

+0

Es stellt tatsächlich das Volumen einer Sicherheit dar, also ist es M (ilions) und möglicherweise B (ilions), aber ich werde mit gerade dem M. glücklich sein. –

+0

[Diese in Verbindung stehende Frage] (http://stackoverflow.com/q/4753251/ 983430) hat in letzter Zeit viel Aufmerksamkeit bekommen (wegen einer Prämie). –

Antwort

17
String.format("%.2fM", theNumber/ 1000000.0); 

Für weitere Informationen die String.format javadocs sehen.

+0

Nur für den Fall: 1.000.000,0 stattdessen verwenden. –

+0

Minor Nitpick, sieht aus wie sein Code Longs oder Ints verwendet, so dass Sie auf die Fließkomma-Arithmetik verzichten können: – wds

+0

Wenn ich die Fließkomma-Mathematik verlassen, würde ich mit einer ganzen Zahl, keine Nachkommastellen verlassen. Wir brauchen mindestens 2. – jjnguy

0

Werfen Sie einen Blick auf ChoiseFormat.

Eine einfachere Möglichkeit wäre, einen Wrapper zu verwenden, der automatisch durch 1m für Sie dividiert wird.

+0

Ich habe einen Blick auf die Dokumentation geworfen, aber ich bin mir nicht sicher, wie mir das hier helfen wird. Scheint, dass ChoiceFormat im Grunde eine Menge von Formaten enthält und die Eingabe irgendwie mit einem dieser Subformate übereinstimmt. Ich denke, ich möchte, dass alle Eingaben gleich gehandhabt werden. –

3

Hier ist eine Unterklasse von NumberFormat, die ich aufpeitschte. Es sieht aus wie es die Arbeit erledigt, aber ich bin mir nicht ganz sicher, dass es der beste Weg:

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..."); 
    } 
}; 
+0

Ich mag die Lösung von Outlaw, zumal es auch k/M/G "menschenlesbare" Formatierung erstellen kann, ohne dass der Benutzer dieser API Berechnungen durchführen muss. Er bekommt immer die kürzest mögliche Nummer. 999.99k 999.99M 999.99G 999.99T – eckes

3

Warum nicht einfach?

DecimalFormat df = new DecimalFormat("0.00M"); 
System.out.println(df.format(n/1000000)); 
+0

Die Division muss innerhalb des Formatierungsprogramms gekapselt werden. Ich schätze, ich werde die Frage aktualisieren, um das Problem, das ich habe, klarer zu erklären. –

4

Beachten Sie, dass, wenn Sie einen BigDecimal haben, können Sie die movePointLeft Methode verwenden:

new DecimalFormat("#.00").format(value.movePointLeft(6));