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);
}
}
BigDecimalcom 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.NumberFormatmé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.
*100e %100sendo tendencioso dos EUA, você poderia usar em Math.pow(10, formatter.getMaximumFractionDigits())vez de um codificado 100para 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.