Java Para Birimi Numarası biçimi


91

Ondalık sayıyı aşağıdaki gibi biçimlendirmenin bir yolu var mı:

100   -> "100"  
100.1 -> "100.10"

Yuvarlak bir sayı ise, ondalık bölümü atlayın. Aksi takdirde iki ondalık basamak içeren biçim.

Yanıtlar:


48

Şüpheliyim. Sorun şu ki, bir float ise 100 asla 100 değildir, normalde 99.9999999999 veya 100.0000001 veya bunun gibi bir şeydir.

Bunu bu şekilde biçimlendirmek istiyorsanız, bir epsilon, yani bir tam sayıdan maksimum uzaklık tanımlamanız ve fark daha küçükse tamsayı biçimlendirmesi, aksi takdirde kayan nokta kullanmanız gerekir.

Bunun gibi bir şey işe yarayabilir:

public String formatDecimal(float number) {
  float epsilon = 0.004f; // 4 tenths of a cent
  if (Math.abs(Math.round(number) - number) < epsilon) {
     return String.format("%10.0f", number); // sdb
  } else {
     return String.format("%10.2f", number); // dj_segfault
  }
}

8
Küçük nitpick: bir kayan nokta, 0x42c80000 bit deseniyle tam olarak 100 olabilir.
Karol S

2
Evet, Karol S'nin belirttiği gibi, birçok sayı tam olarak şamandıralarla eşleştirilebilir. Sadece TÜM sayılar değil. 100, temsil edilebilecek bir sayıdır, sadece olamayacak sayıları hesaba katmalısınız.
csga5000

160

Java.text paketini kullanmanızı tavsiye ederim:

double money = 100.1;
NumberFormat formatter = NumberFormat.getCurrencyInstance();
String moneyString = formatter.format(money);
System.out.println(moneyString);

Bunun yerel ayara özgü olma ek yararı vardır.

Ancak, mecbur kalırsanız, tam bir dolarsa geri alırsınız:

if (moneyString.endsWith(".00")) {
    int centsIndex = moneyString.lastIndexOf(".00");
    if (centsIndex != -1) {
        moneyString = moneyString.substring(1, centsIndex);
    }
}

17
Para birimlerini temsil etmek için asla çift kullanmamalısınız. Ya uzunlara dönüştürün ve ondalık noktayı kendiniz yönetin ya BigDecimalda bir formatlayıcı ile kullanın . joda-money.sourceforge.net , bittiğinde kullanmak için güzel bir kitaplık olmalıdır.
gpampara

5
Yeniden: çifte! = Paraya katılıyorum, ancak soru bu şekilde sorulmadı.
duffymo

3
Para birimleri böyle ne demek? 1 dolara mal olan bir şeyin 1.00 dolara mal olmadığını söyleyebilirim .... para birimlerini göstermenin farklı bir yolu vardır (varsayılandan farklı) ve bu soru ondalık kısmın bir tamsayı ise nasıl çıkarılacağını sorar.
DD.

1
Bu bir oluşturma sorunu. Para birimini bir Dize olarak kabul etmek ve tam bir dolar ise ondalık ve senti kesmek için mantığı UI'nize yerleştirin.
duffymo

2
Kabul edildi - bu yüzden 5.5 yıl önce bunu yazarken Locale'i kullanmanızı tavsiye ettim. "Ama gerekirse, ...." anahtar sözcüktür.
duffymo

126
double amount =200.0;
Locale locale = new Locale("en", "US");      
NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(locale);
System.out.println(currencyFormatter.format(amount));

veya

double amount =200.0;
System.out.println(NumberFormat.getCurrencyInstance(new Locale("en", "US"))
        .format(amount));

Para birimini görüntülemenin en iyi yolu

Çıktı

200,00 $

İşaret kullanmak istemiyorsanız bu yöntemi kullanın

double amount = 200;
DecimalFormat twoPlaces = new DecimalFormat("0.00");
System.out.println(twoPlaces.format(amount));

200,00

Bu da kullanılabilir (Binlik ayırıcı ile)

double amount = 2000000;    
System.out.println(String.format("%,.2f", amount));          

2.000.000,00


Belirtildikten sonra "para birimi" referans verilmiş veya kullanılmış gibi görünmüyor ... 3. satırın bir yan etkisi var mı? Veya eklemenizin bir nedeni mi?
Damian

[Class Locale] [1] [1] hakkında daha fazla bilgi edinin: docs.oracle.com/javase/7/docs/api/java/util/…
Thilina Dharmasena

18

Google aramasından sonra iyi bir çözüm bulamadım, sadece çözümümü referans olarak diğerine gönderin. parayı biçimlendirmek için priceToString kullanın.

public static String priceWithDecimal (Double price) {
    DecimalFormat formatter = new DecimalFormat("###,###,###.00");
    return formatter.format(price);
}

public static String priceWithoutDecimal (Double price) {
    DecimalFormat formatter = new DecimalFormat("###,###,###.##");
    return formatter.format(price);
}

public static String priceToString(Double price) {
    String toShow = priceWithoutDecimal(price);
    if (toShow.indexOf(".") > 0) {
        return priceWithDecimal(price);
    } else {
        return priceWithoutDecimal(price);
    }
}

Daha iyi olduğunu hiç söylemedi. Başkalarının da başvurabilmesi için çözümünü yayınladı. En azından bir teşekkür diyebilirsin.
Umang Desai

1
Fiyatı Hint formatında görüntülemek istersem ne olur? Ondalık sayılar olmadan. Biçim -> ##, ##, ###
Bhuvan

PriceWithDecimal (Çift) yöntemde, maske değiştirmeyi deneyin "###,###,###.00"için "###,###,##0.00"değer "0" olduğunda "0,00" göstermek için
dellasavia

1
biçimlendirilmiş para birimini tekrar
Double'a

6

Evet. Java.util.formatter'ı kullanabilirsiniz . "% 10.2f" gibi bir biçimlendirme dizesi kullanabilirsiniz


String.format()bunun için güzel bir statik paketleyicidir. Yine de neden "10" kullandığınızdan emin değilim.
Xr.

Numaranın boyutuyla ilgili herhangi bir yönlendirme olmadığından, 10 Ex Recto seçtim. Bunun bir çikolatanın mı yoksa bir arabanın mı fiyatı olduğunu bilmiyoruz. Toplam boyutu sınırsız bırakmak için sadece "% .2f" yapabileceğine inanıyorum.
dj_segfault

Miktar yuvarlak bir para birimi sayısı ise DD, ondalık kısmın çıkarılmasını istedi.
jarnbjo

6

Bunu kullanıyorum (commons-lang'dan StringUtils kullanarak):

Double qty = 1.01;
String res = String.format(Locale.GERMANY, "%.2f", qty);
String fmt = StringUtils.removeEnd(res, ",00");

Yalnızca yerel ayara ve kesilecek ilgili String'e dikkat etmelisiniz.


5

Para birimi basmak için bunun basit ve anlaşılır olduğunu düşünüyorum:

DecimalFormat df = new DecimalFormat("$###,###.##"); // or pattern "###,###.##$"
System.out.println(df.format(12345.678));

çıktı: 12.345,68 $

Ve soru için olası çözümlerden biri:

public static void twoDecimalsOrOmit(double d) {
    System.out.println(new DecimalFormat(d%1 == 0 ? "###.##" : "###.00").format(d));
}

twoDecimalsOrOmit((double) 100);
twoDecimalsOrOmit(100.1);

Çıktı:

100

100.10


Gönderinin amacını kaçırdınız. Sayı bir tamsayı ise, ondalık sayıları görüntülemek istemiyorum.
DD.

DD. Üzgünüm ve cevabı soruya göre düzelttim.
Andrew

5

Genellikle tersini yapmamız gerekecek, eğer json para alanınız bir float ise, 3.1, 3.15 veya sadece 3 olarak gelebilir.

Bu durumda, düzgün bir görüntü için onu yuvarlamanız gerekebilir (ve daha sonra bir giriş alanında bir maske kullanabilmeniz için):

floatvalue = 200.0; // it may be 200, 200.3 or 200.37, BigDecimal will take care
Locale locale = new Locale("en", "US");      
NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(locale);

BigDecimal valueAsBD = BigDecimal.valueOf(value);
    valueAsBD.setScale(2, BigDecimal.ROUND_HALF_UP); // add digits to match .00 pattern

System.out.println(currencyFormatter.format(amount));

5

bunu yapmanın en iyi yolu budur.

    public static String formatCurrency(String amount) {
        DecimalFormat formatter = new DecimalFormat("###,###,##0.00");
        return formatter.format(Double.parseDouble(amount));
    }

100 -> "100.00"
100.1 -> "100.10"


5
NumberFormat currency = NumberFormat.getCurrencyInstance();
String myCurrency = currency.format(123.5);
System.out.println(myCurrency);

çıktı:

$123.50

Para birimini değiştirmek istiyorsanız,

NumberFormat currency = NumberFormat.getCurrencyInstance(Locale.CHINA);
String myCurrency = currency.format(123.5);
System.out.println(myCurrency);

çıktı:

123.50

4

bunun gibi bir şey yapmalısın:

public static void main(String[] args) {
    double d1 = 100d;
    double d2 = 100.1d;
    print(d1);
    print(d2);
}

private static void print(double d) {
    String s = null;
    if (Math.round(d) != d) {
        s = String.format("%.2f", d);
    } else {
        s = String.format("%.0f", d);
    }
    System.out.println(s);
}

hangi yazdırır:

100

100,10


Math.round (d)! = D çalışacak mı? Yüzer ile sık sık! = Öyle olduğunu düşünseniz bile.
extraneon

1
diğer taraftan, d 100.000000000000001 olsaydı, o zaman yine 100 olarak basılacaktır
Stefan De Boey

4

Bunun eski bir soru olduğunu biliyorum ama ...

import java.text.*;

public class FormatCurrency
{
    public static void main(String[] args)
    {
        double price = 123.4567;
        DecimalFormat df = new DecimalFormat("#.##");
        System.out.print(df.format(price));
    }
}

3
Bu işe yaramaz, örneğin 100.1 -> "100.1" yapar - bkz. Stackoverflow.com/questions/5033404/…
davnicwil

4

Bunun gibi bir şey yapabilir ve tam sayıyı ve ardından senti geçebilirsiniz.

String.format("$%,d.%02d",wholeNum,change);

4

java.text.NumberFormatBu tür şeyler için yöntemleri kullanmanız gerektiği konusunda @duffymo'ya katılıyorum . Aslında tüm biçimlendirmeyi kendi içinde herhangi bir String yapmadan yerel olarak yapabilirsiniz:

private String formatPrice(final double priceAsDouble) 
{
    NumberFormat formatter = NumberFormat.getCurrencyInstance();
    if (Math.round(priceAsDouble * 100) % 100 == 0) {
        formatter.setMaximumFractionDigits(0);
    }
    return formatter.format(priceAsDouble);
}

Gösterilecek birkaç bit:

  • Bütün Math.round(priceAsDouble * 100) % 100 , sadece çiftlerin / yüzdürmelerin yanlışlıkları etrafında çalışıyor. Temelde sadece yüzlerce yere yuvarlanıp yuvarlanmadığımızı kontrol etmek (belki bu bir ABD önyargısıdır), kalan sentlerin var mı?
  • Ondalık sayıları kaldırmanın püf noktası setMaximumFractionDigits()yöntemdir

Ondalık sayıların kesilip kesilmeyeceğini belirlemek için mantığınız ne olursa setMaximumFractionDigits()olsun kullanılmalıdır.


1
Hakkında noktadan yeniden *100ve %100ABD-önyargılı şunu kullanabilirsiniz Math.pow(10, formatter.getMaximumFractionDigits())yerine kodlanmış bir 100yerel ayar için doğru numarayı kullanmak ...
daiscog

3

Para birimleri üzerinde çalışmak istiyorsanız, BigDecimal sınıfını kullanmanız gerekir. Sorun şu ki, bazı kayan sayıları bellekte saklamanın bir yolu yoktur (örn. 5.3456 saklayabilirsiniz ama 5.3455 saklayamazsınız), bu da kötü hesaplamaları etkileyebilir.

BigDecimal ve para birimleri ile nasıl işbirliği yapılacağına dair güzel bir makale var:

http://www.javaworld.com/javaworld/jw-06-2001/jw-0601-cents.html


2
Bu, sorduğum soru ile tamamen alakasız.
DD.

3

1000000,2 ile 1 000 000,20 arasında biçimlendirme

private static final DecimalFormat DF = new DecimalFormat();

public static String toCurrency(Double d) {
    if (d == null || "".equals(d) || "NaN".equals(d)) {
        return " - ";
    }
    BigDecimal bd = new BigDecimal(d);
    bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
    DecimalFormatSymbols symbols = DF.getDecimalFormatSymbols();
    symbols.setGroupingSeparator(' ');
    String ret = DF.format(bd) + "";
    if (ret.indexOf(",") == -1) {
        ret += ",00";
    }
    if (ret.split(",")[1].length() != 2) {
        ret += "0";
    }
    return ret;
}

2

Bu gönderi, sonunda istediğimi elde etmeme gerçekten yardımcı oldu. Bu yüzden başkalarına yardım etmek için koduma buraya katkıda bulunmak istedim. İşte kodum ve bazı açıklamalar.

Aşağıdaki kod:

double moneyWithDecimals = 5.50;
double moneyNoDecimals = 5.00;
System.out.println(jeroensFormat(moneyWithDecimals));
System.out.println(jeroensFormat(moneyNoDecimals));

Dönecek:

5,-
€ 5,50

Gerçek jeroensFormat () yöntemi:

public String jeroensFormat(double money)//Wants to receive value of type double
{
        NumberFormat dutchFormat = NumberFormat.getCurrencyInstance();
        money = money;
        String twoDecimals = dutchFormat.format(money); //Format to string
        if(tweeDecimalen.matches(".*[.]...[,]00$")){
            String zeroDecimals = twoDecimals.substring(0, twoDecimals.length() -3);
                return zeroDecimals;
        }
        if(twoDecimals.endsWith(",00")){
            String zeroDecimals = String.format("€ %.0f,-", money);
            return zeroDecimals; //Return with ,00 replaced to ,-
        }
        else{ //If endsWith != ,00 the actual twoDecimals string can be returned
            return twoDecimals;
        }
}

JeroensFormat () yöntemini çağıran displayJeroensFormat yöntemi

    public void displayJeroensFormat()//@parameter double:
    {
        System.out.println(jeroensFormat(10.5)); //Example for two decimals
        System.out.println(jeroensFormat(10.95)); //Example for two decimals
        System.out.println(jeroensFormat(10.00)); //Example for zero decimals
        System.out.println(jeroensFormat(100.000)); //Example for zero decimals
    }

Aşağıdaki çıktıya sahip olacak:

10,5010,9510,-
€ 100.000 (In Holland numbers bigger than € 999,- and wit no decimals don't have ,-)

Bu kod, mevcut para biriminizi kullanır. Benim durumumda Hollanda bu yüzden benim için biçimlendirilmiş dize ABD'deki birinden farklı olacak.

  • Hollanda: 999.999,99
  • ABD: 999.999,99

Sadece bu sayıların son 3 karakterini izleyin. Kodumda son 3 karakterin ", 00" ile eşit olup olmadığını kontrol etmek için bir if ifadesi var. Bunu ABD'de kullanmak için eğer zaten çalışmıyorsa ".00" olarak değiştirmeniz gerekebilir.


2

Kendi işlevimi yazacak kadar deliydim:

Bu, tamsayıyı para birimi biçimine dönüştürecektir (ondalık sayılar için de değiştirilebilir):

 String getCurrencyFormat(int v){
        String toReturn = "";
        String s =  String.valueOf(v);
        int length = s.length();
        for(int i = length; i >0 ; --i){
            toReturn += s.charAt(i - 1);
            if((i - length - 1) % 3 == 0 && i != 1) toReturn += ',';
        }
        return "$" + new StringBuilder(toReturn).reverse().toString();
    }

2
  public static String formatPrice(double value) {
        DecimalFormat formatter;
        if (value<=99999)
          formatter = new DecimalFormat("###,###,##0.00");
        else
            formatter = new DecimalFormat("#,##,##,###.00");

        return formatter.format(value);
    }

2

Para birimini biçimlendirmek isteyen ancak yerel olmasını istemeyenler için şunu yapabiliriz:

val numberFormat = NumberFormat.getCurrencyInstance() // Default local currency
val currency = Currency.getInstance("USD")            // This make the format not locale specific 
numberFormat.setCurrency(currency)

...use the formator as you want...

1

Bunun yerine tutarı sent olarak göstermek için bir tamsayı kullanarak yaptığım şey buydu:

public static String format(int moneyInCents) {
    String format;
    Number value;
    if (moneyInCents % 100 == 0) {
        format = "%d";
        value = moneyInCents / 100;
    } else {
        format = "%.2f";
        value = moneyInCents / 100.0;
    }
    return String.format(Locale.US, format, value);
}

İle ilgili sorun NumberFormat.getCurrencyInstance() şu ki, bazen 20 $ 'ın gerçekten 20 $ olmasını istiyorsunuz, sadece 20.00 $' dan daha iyi görünüyor.

NumberFormat kullanarak bunu yapmanın daha iyi bir yolunu bulan varsa, kulaklarım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.