Formatar Flutuar em n casas decimais


220

Eu preciso formatar um float para "n" casas decimais.

estava tentando BigDecimal, mas o valor de retorno não está correto ...

public static float Redondear(float pNumero, int pCantidadDecimales) {
    // the function is call with the values Redondear(625.3f, 2)
    BigDecimal value = new BigDecimal(pNumero);
    value = value.setScale(pCantidadDecimales, RoundingMode.HALF_EVEN); // here the value is correct (625.30)
    return value.floatValue(); // but here the values is 625.3
}

Preciso retornar um valor flutuante com o número de casas decimais que eu especificar.

Preciso de Floatretorno de valor nãoDouble

.

Respostas:


561

Você também pode passar o valor flutuante e usar:

String.format("%.2f", floatValue);

Documentação


70
Tenha cuidado, pois String.format depende da sua configuração local atual; talvez você não consiga um ponto como separador. Prefira usarString.format(java.util.Locale.US,"%.2f", floatValue);
Gomino 2/16

6
esta resposta fornece um valor String, não um valor Float, não acho uma boa resposta.
ZhaoGang

3
Por que você força um ponto como separador?
Mark Buikema

1
@ MarkBuikema Acho que há casos em que isso seria absolutamente necessário, como na compilação de formatos de documentos conduzidos por padrões, por exemplo. Documentos em PDF.
precisa saber é o seguinte

39

Dê uma olhada em DecimalFormat . Você pode usá-lo facilmente para pegar um número e atribuir um número definido de casas decimais.

Editar : Exemplo


1
+1. Aqui está a documentação específica do Android , que deve ser essencialmente a mesma.
Zach G

mas preciso que o resultado seja um número flutuante, não uma string.
precisa saber é o seguinte

Você está dizendo que deseja contornar a bóia? Normalmente, a única precisão de tempo de um flutuador é importante para exibição.
Nick Campion

desculpe, você está certo, eu estava confuso, apenas formate o número quando mostrado na tela, não antes, essa foi a minha pergunta, muito obrigado, problema resolvido.
precisa saber é o seguinte

Note que o uso do DecimalFormatconstrutor é desencorajado; veja minha resposta para um uso correto de NumberFormat.
FBB

17

Tente isso, isso me ajudou muito

BigDecimal roundfinalPrice = new BigDecimal(5652.25622f).setScale(2,BigDecimal.ROUND_HALF_UP);

O resultado será final da RodadaPreço -> 5652.26


2
Isso é mais útil para quem procura arredondar e fazer alguns cálculos adicionais, caso contrário, a resposta de Arve é provavelmente a melhor.
Gerard

Isso funciona com o GWT também. String.format () - não.
26418 AlexV

15

De notar, o uso do DecimalFormatconstrutor é desencorajado. O javadoc para esta classe declara:

Em geral, não chame os construtores DecimalFormat diretamente, pois os métodos de fábrica NumberFormat podem retornar subclasses diferentes de DecimalFormat.

https://docs.oracle.com/javase/8/docs/api/java/text/DecimalFormat.html

Então, o que você precisa fazer é (por exemplo):

NumberFormat formatter = NumberFormat.getInstance(Locale.US);
formatter.setMaximumFractionDigits(2);
formatter.setMinimumFractionDigits(2);
formatter.setRoundingMode(RoundingMode.HALF_UP); 
Float formatedFloat = new Float(formatter.format(floatValue));

Isso não está funcionando quando (por exemplo) floatValue = 8.499. Está dando 8.5.
Shiva krishna Chippa

3
@ShivakrishnaChippa: sim, porque aqui especificamos que queremos 2 dígitos após a vírgula e fazer um arredondamento para cima. Nesse caso, 8.499 é arredondado para 8,5. Se você deseja que 8.499 seja exibido, basta definir 3 como o número máximo de frações.
FBB

6

Aqui está uma amostra rápida usando a DecimalFormatclasse mencionada por Nick.

float f = 12.345f;
DecimalFormat df = new DecimalFormat("#.00");
System.out.println(df.format(f));

A saída da declaração de impressão será 12.35. Observe que o arredondará para você.


Note que o uso do DecimalFormatconstrutor é desencorajado; veja minha resposta para um uso correto de NumberFormat.
FBB

5

Meio surpreso que ninguém apontou o caminho direto para fazê-lo, o que é bastante fácil.

double roundToDecimalPlaces(double value, int decimalPlaces)
{
      double shift = Math.pow(10,decimalPlaces);
      return Math.round(value*shift)/shift;
}

Certamente, isso não faz o arredondamento pela metade.

Pelo que vale, o arredondamento semi-uniforme será caótico e imprevisível sempre que você misturar valores de ponto flutuante baseados em binário com aritmética da base 10. Tenho certeza que isso não pode ser feito. O problema básico é que um valor como 1.105 não pode ser representado exatamente no ponto flutuante. O valor do ponto flutuante será algo como 1.105000000000001 ou 1.104999999999999. Portanto, qualquer tentativa de realizar arredondamentos semitransparentes ocorre com erros de codificação representacional.

As implementações de ponto flutuante IEEE farão meio arredondamento, mas farão meio arredondamento binário, não arredondamento decimal. Então você provavelmente está bem


Também usei esse método por um tempo, mas acho que powé uma operação muito cara para usar no arredondamento?
Xerus

Nunca otimize até ter um problema de desempenho. Mais importante estar certo do que rápido. E não posso honestamente imaginar uma aplicação em que o desempenho do arredondamento controlado seja um problema, a menos que você seja Visa ou Mastercard (que jogaria mais máquinas nele). E pow () é provavelmente mais rápido que o round ().
Robin Davies

2
public static double roundToDouble(float d, int decimalPlace) {
        BigDecimal bd = new BigDecimal(Float.toString(d));
        bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
        return bd.doubleValue();
    }

2

Essa é uma maneira muito menos profissional e muito mais cara, mas deve ser mais fácil de entender e mais útil para iniciantes.

public static float roundFloat(float F, int roundTo){

    String num = "#########.";

    for (int count = 0; count < roundTo; count++){
        num += "0";
    }

    DecimalFormat df = new DecimalFormat(num);

    df.setRoundingMode(RoundingMode.HALF_UP);

    String S = df.format(F);
    F = Float.parseFloat(S);

    return F;
}

1

Eu acho que o que você quer é

return value.toString();

e use o valor de retorno para exibir.

value.floatValue();

sempre retornará 625,3 porque é usado principalmente para calcular algo.


mas preciso que o resultado seja um número flutuante, não uma string.
precisa saber é o seguinte

2
se você precisar de um flutuador para mostrá-lo ao usuário, pode haver algo errado com o design do aplicativo. Normalmente, o float é usado para calcular e uma string é usada para mostrá-lo ao usuário.
N3utrino 5/03

desculpe, você está certo, eu estava confuso, apenas formate o número quando mostrado na tela, não antes, essa foi a minha pergunta, muito obrigado, problema resolvido.
precisa saber é o seguinte

1

Eu estava procurando uma resposta para esta pergunta e depois desenvolvi um método! :) Um aviso justo, está arredondando o valor.

private float limitDigits(float number) {
    return Float.valueOf(String.format(Locale.getDefault(), "%.2f", number));
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.