Existe uma maneira de formatar um decimal da seguinte forma:
100 -> "100"
100.1 -> "100.10"
Se for um número redondo, omita a parte decimal. Caso contrário, formate com duas casas decimais.
Respostas:
Eu duvido. O problema é que 100 nunca é 100 se for um float, normalmente é 99,9999999999 ou 100,0000001 ou algo parecido.
Se você quiser formatar dessa forma, terá que definir um épsilon, ou seja, uma distância máxima de um número inteiro, e usar a formatação inteira se a diferença for menor, e um float caso contrário.
Algo como isso resolveria o problema:
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
}
}
Eu recomendo usar o pacote java.text:
double money = 100.1;
NumberFormat formatter = NumberFormat.getCurrencyInstance();
String moneyString = formatter.format(money);
System.out.println(moneyString);
Isso tem a vantagem adicional de ser específico do local.
Mas, se necessário, trunque a string que você recebe de volta se for um dólar inteiro:
if (moneyString.endsWith(".00")) {
int centsIndex = moneyString.lastIndexOf(".00");
if (centsIndex != -1) {
moneyString = moneyString.substring(1, centsIndex);
}
}
BigDecimal
com um formatador. joda-money.sourceforge.net deve ser uma boa biblioteca para usar quando estiver pronto.
double amount =200.0;
Locale locale = new Locale("en", "US");
NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(locale);
System.out.println(currencyFormatter.format(amount));
ou
double amount =200.0;
System.out.println(NumberFormat.getCurrencyInstance(new Locale("en", "US"))
.format(amount));
A melhor maneira de exibir moeda
Resultado
$ 200,00
Se você não quiser usar sinal, use este método
double amount = 200;
DecimalFormat twoPlaces = new DecimalFormat("0.00");
System.out.println(twoPlaces.format(amount));
200,00
Isso também pode ser usado (com o separador de milhar)
double amount = 2000000;
System.out.println(String.format("%,.2f", amount));
2.000.000,00
Não achei nenhuma solução boa após a busca no google, apenas poste minha solução para outra referência. use priceToString para formatar dinheiro.
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);
}
}
"###,###,###.00"
para "###,###,##0.00"
mostrar "0,00" quando o valor for "0"
Sim. Você pode usar java.util.formatter . Você pode usar uma string de formatação como "% 10.2f"
String.format()
é um bom wrapper estático para isso. Não sei por que você usa '10', no entanto.
Estou usando este (usando StringUtils de commons-lang):
Double qty = 1.01;
String res = String.format(Locale.GERMANY, "%.2f", qty);
String fmt = StringUtils.removeEnd(res, ",00");
Você só deve cuidar da localidade e da String correspondente para cortar.
Acho que isso é simples e claro para imprimir uma moeda:
DecimalFormat df = new DecimalFormat("$###,###.##"); // or pattern "###,###.##$"
System.out.println(df.format(12345.678));
produção: $ 12.345,68
E uma das soluções possíveis para a questão:
public static void twoDecimalsOrOmit(double d) {
System.out.println(new DecimalFormat(d%1 == 0 ? "###.##" : "###.00").format(d));
}
twoDecimalsOrOmit((double) 100);
twoDecimalsOrOmit(100.1);
Resultado:
100
100,10
Normalmente precisaremos fazer o inverso, se o seu campo de dinheiro json for um float, pode vir como 3.1, 3.15 ou apenas 3.
Neste caso, você pode precisar arredondá-lo para uma exibição adequada (e para poder usar uma máscara em um campo de entrada posteriormente):
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));
esta é a melhor maneira de fazer isso.
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"
NumberFormat currency = NumberFormat.getCurrencyInstance();
String myCurrency = currency.format(123.5);
System.out.println(myCurrency);
resultado:
$123.50
Se você quiser mudar a moeda,
NumberFormat currency = NumberFormat.getCurrencyInstance(Locale.CHINA);
String myCurrency = currency.format(123.5);
System.out.println(myCurrency);
resultado:
¥123.50
você deve fazer algo assim:
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);
}
que imprime:
100
100,10
Eu sei que esta é uma pergunta antiga, mas ...
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));
}
}
Você pode simplesmente fazer algo assim e passar o número inteiro e depois os centavos.
String.format("$%,d.%02d",wholeNum,change);
Eu concordo com @duffymo que você precisa usar os java.text.NumberFormat
métodos para esse tipo de coisas. Na verdade, você pode fazer toda a formatação nativamente sem fazer nenhuma comparação de String:
private String formatPrice(final double priceAsDouble)
{
NumberFormat formatter = NumberFormat.getCurrencyInstance();
if (Math.round(priceAsDouble * 100) % 100 == 0) {
formatter.setMaximumFractionDigits(0);
}
return formatter.format(priceAsDouble);
}
Algumas coisas para apontar:
Math.round(priceAsDouble * 100) % 100
é apenas contornar as imprecisões de duplos / flutuantes. Basicamente, apenas verificando se arredondamos para a casa das centenas (talvez seja um viés dos EUA), há centavos restantes. setMaximumFractionDigits()
métodoQualquer que seja sua lógica para determinar se os decimais devem ou não ser truncados, setMaximumFractionDigits()
deve ser usada.
*100
e %100
sendo tendencioso dos EUA, você poderia usar em Math.pow(10, formatter.getMaximumFractionDigits())
vez de um codificado 100
para usar o número correto para o local ...
Se você quer trabalhar com moedas, tem que usar a classe BigDecimal. O problema é que não há como armazenar alguns números flutuantes na memória (por exemplo, você pode armazenar 5,3456, mas não 5,3455), o que pode afetar cálculos ruins.
Há um bom artigo sobre como cooperar com BigDecimal e moedas:
http://www.javaworld.com/javaworld/jw-06-2001/jw-0601-cents.html
Formato de 1000000,2 a 1 000 000,20
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;
}
Esse post realmente me ajudou a finalmente conseguir o que desejo. Então, eu só queria contribuir com meu código aqui para ajudar outras pessoas. Aqui está meu código com algumas explicações.
O seguinte código:
double moneyWithDecimals = 5.50;
double moneyNoDecimals = 5.00;
System.out.println(jeroensFormat(moneyWithDecimals));
System.out.println(jeroensFormat(moneyNoDecimals));
Retornará:
€ 5,-
€ 5,50
O método jeroensFormat () real:
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;
}
}
O método displayJeroensFormat que chama o método jeroensFormat ()
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
}
Terá a seguinte saída:
€ 10,50
€ 10,95
€ 10,-
€ 100.000 (In Holland numbers bigger than € 999,- and wit no decimals don't have ,-)
Este código usa sua moeda atual. No meu caso, é a Holanda, então a string formatada para mim será diferente do que para alguém nos EUA.
Observe os últimos 3 caracteres desses números. Meu código tem uma declaração if para verificar se os últimos 3 caracteres são iguais a ", 00". Para usar isso nos EUA, você pode ter que mudar para ".00" se ainda não funcionar.
Eu fui louco o suficiente para escrever minha própria função:
Isso converterá o formato inteiro para moeda (pode ser modificado para decimais também):
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();
}
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);
}
Para as pessoas que desejam formatar a moeda, mas não querem que seja baseada no local, podemos fazer o seguinte:
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...
Isso é o que eu fiz, usando um número inteiro para representar o valor em centavos:
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);
}
O problema com NumberFormat.getCurrencyInstance()
é que às vezes você realmente quer $ 20 como $ 20, mas parece melhor do que $ 20,00.
Se alguém encontrar uma maneira melhor de fazer isso, usando NumberFormat, sou todo ouvidos.