2009-02-09 30 views
8

Có cách nào để sử dụng DecimalFormat (hoặc một số định dạng tiêu chuẩn khác) đến các số định dạng như thế này:Java: Format number trong hàng triệu

1.000.000 => 1.00M

1.234.567 => 1.23M

1234567890 => 1234.57M

về cơ bản chia một số số 1 triệu USD, giữ 2 chữ số thập phân, và tát một 'M' ở cuối dòng. Tôi đã nghĩ về việc tạo ra một phân lớp mới của NumberFormat nhưng nó trông phức tạp hơn tôi tưởng tượng.

Tôi đang viết một API mà có một phương pháp định dạng trông như thế này:

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

Bên trong, tôi đối tượng Đơn vị lập bản đồ để NumberFormatters. Việc thực hiện là một cái gì đó như thế này:

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

Lưu ý rằng vì điều này, tôi không thể mong đợi khách hàng để chia cho 1 triệu, và tôi không thể chỉ cần sử dụng String.format() mà không cần gói nó trong một NumberFormatter.

+0

Bạn có muốn xử lý M (EGA) mà thôi, hoặc cũng (G) IgA, (T) kỷ nguyên , v.v. –

+0

Nó thực sự đại diện cho một khối lượng bảo mật, do đó, nó là M (illions) và có khả năng B (illions) nhưng tôi sẽ được hạnh phúc với chỉ M. –

+0

[Câu hỏi liên quan này] (http://stackoverflow.com/q/4753251/ 983430) đã nhận được nhiều sự chú ý gần đây (do tiền thưởng). –

Trả lời

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

Để biết thêm thông tin xem các String.format javadocs.

+0

Chỉ trong trường hợp: sử dụng 1.000.000,0 để thay thế. –

+0

Nitor nhỏ, có vẻ như mã của anh ta đang sử dụng longs hoặc ints để bạn có thể phân chia bằng số học dấu phẩy động: – wds

+0

Nếu tôi rời khỏi phép toán dấu chấm động, tôi sẽ bị bỏ lại với số nguyên, không có chữ số thập phân nào cả. Chúng ta cần ít nhất 2. – jjnguy

0

Hãy xem ChoiseFormat.

Cách đơn giản hơn sẽ là sử dụng trình bao bọc được tự động chia cho 1m cho bạn.

+0

Đã xem xét tài liệu nhưng tôi thực sự không chắc chắn cách thức đó sẽ giúp tôi ở đây. Có vẻ như ChoiceFormat về cơ bản chứa một loạt các định dạng và bằng cách nào đó khớp với đầu vào với một trong các định dạng phụ này. Tôi nghĩ rằng tôi muốn tất cả các đầu vào được xử lý như nhau. –

3

Đây là lớp con của NumberFormat mà tôi đã bỏ qua. Có vẻ như nó không được công việc nhưng tôi không hoàn toàn chắc chắn đó là cách tốt nhất:

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

Tôi thích giải pháp từ Outlaw, đặc biệt là vì nó cũng có thể tạo ra định dạng k/M/G "con người có thể đọc được" mà không cần người dùng api này thực hiện các phép tính. Anh ấy luôn nhận được con số ngắn nhất có thể. 999.99k 999.99M 999.99G 999.99T – eckes

3

Tại sao không đơn giản?

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

Việc chia cần phải được đóng gói bên trong trình định dạng. Đoán tôi sẽ cập nhật câu hỏi để giải thích rõ hơn vấn đề tôi đang gặp phải. –

4

Lưu ý rằng nếu bạn có một BigDecimal, bạn có thể sử dụng movePointLeft phương pháp:

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