Formato de flotación a n decimales

220

Necesito formatear un flotador a "n" decimales.

estaba intentando BigDecimal, pero el valor de retorno no es correcto ...

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
}

Necesito devolver un valor flotante con el número de decimales que especifico.

Necesito Floatvalor de retorno noDouble

.

seba123neo
fuente

Respuestas:

561

También puede pasar el valor flotante y usar:

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

Documentación

Arve
fuente
70
Tenga cuidado ya que String.format depende de su configuración local actual, es posible que no obtenga un punto como separador. Prefiero usarString.format(java.util.Locale.US,"%.2f", floatValue);
Gomino
66
esta respuesta da un valor de cadena, no un valor flotante, no creo que sea una buena respuesta.
ZhaoGang
3
¿Por qué forzarías un punto como separador?
Mark Buikema
1
@ MarkBuikema Creo que hay casos en los que sería absolutamente necesario, como cuando se compilan formatos de documentos basados ​​en estándares, por ejemplo. Documentos PDF.
Tjaart el
39

Echa un vistazo a DecimalFormat . Puede usarlo fácilmente para tomar un número y asignarle un número determinado de decimales.

Editar : Ejemplo

Nick Campion
fuente
1
+1. Aquí está la documentación específica de Android , que debería ser esencialmente la misma.
Zach L
pero necesito que el resultado sea un número flotante, no una cadena.
seba123neo
¿Estás diciendo que quieres redondear el flotador? Normalmente, la única precisión de tiempo de un flotador es para la visualización.
Nick Campion
lo siento, tienes razón, estaba confundido, solo formatea el número cuando se muestra en la pantalla, no antes, esa fue mi pregunta, muchas gracias, problema resuelto.
seba123neo
Cabe destacar que DecimalFormatse desaconseja el uso del constructor, vea mi respuesta para un uso correcto de NumberFormat.
FBB
17

Prueba esto, esto me ayudó mucho

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

El resultado será roundfinalPrice -> 5652.26

Anupam
fuente
2
Esto es más útil para aquellos que buscan redondear y hacer algunos cálculos adicionales con él, de lo contrario, la respuesta de Arve es probablemente la mejor.
Gerard
Esto también funciona con GWT. String.format (): no.
AlexV
15

Es de destacar que DecimalFormatse desaconseja el uso del constructor. El javadoc para esta clase dice:

En general, no llame a los constructores DecimalFormat directamente, ya que los métodos de fábrica NumberFormat pueden devolver subclases que no sean DecimalFormat.

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

Entonces, lo que debe hacer es (por ejemplo):

NumberFormat formatter = NumberFormat.getInstance(Locale.US);
formatter.setMaximumFractionDigits(2);
formatter.setMinimumFractionDigits(2);
formatter.setRoundingMode(RoundingMode.HALF_UP); 
Float formatedFloat = new Float(formatter.format(floatValue));
FBB
fuente
Esto no funciona cuando (por ejemplo) floatValue = 8.499. Está dando 8.5.
Shiva krishna Chippa
3
@ ShivakrishnaChippa: sí, porque aquí especificamos que queremos 2 dígitos después de la coma y hacer un redondeo hacia arriba. En ese caso, 8.499 se redondea a 8.5. Si desea que se muestre 8.499, simplemente configure 3 como la fracción máxima de dígitos.
FBB
6

Aquí hay una muestra rápida usando la DecimalFormatclase mencionada por Nick.

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

El resultado de la declaración de impresión será 12.35. Tenga en cuenta que lo redondeará por usted.

Tony L.
fuente
Es de destacar que no se recomienda el uso del DecimalFormatconstructor, vea mi respuesta para un uso correcto de NumberFormat.
FBB
5

Un poco sorprendido de que nadie haya señalado la forma directa de hacerlo, lo cual es bastante fácil.

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

Sin embargo, estoy bastante seguro de que esto no hace redondeo a medias.

Por lo que vale, el redondeo a la mitad será caótico e impredecible cada vez que mezcle valores de punto flotante basados ​​en binarios con aritmética de base 10. Estoy bastante seguro de que no se puede hacer. El problema básico es que un valor como 1.105 no se puede representar exactamente en coma flotante. El valor de coma flotante será algo así como 1.105000000000001 o 1.104999999999999. Por lo tanto, cualquier intento de realizar redondeos a medias se tropezará con errores de codificación representativa.

Las implementaciones de punto flotante IEEE harán medio redondeo, pero hacen medio redondeo binario, no medio redondeo decimal. Entonces probablemente estés bien

Robin Davies
fuente
También he usado este método por un tiempo, pero creo que powes una operación demasiado costosa para redondear.
Xerus
Nunca optimices hasta que realmente tengas un problema de rendimiento. Más importante tener razón que rápido. Y honestamente, no puedo imaginar una aplicación donde el rendimiento del redondeo controlado sea un problema, a menos que usted sea Visa o Mastercard (que simplemente le arrojaría más máquinas). Y pow () es probablemente más rápido que 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();
    }
M. Usman Khan
fuente
2

Esta es una forma mucho menos profesional y mucho más costosa, pero debería ser más fácil de entender y más útil para los principiantes.

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;
}
Ethan Johnson
fuente
1

Creo que lo que quieres es

return value.toString();

y use el valor de retorno para mostrar.

value.floatValue();

siempre devolverá 625.3 porque se usa principalmente para calcular algo.

n3utrino
fuente
pero necesito que el resultado sea un número flotante, no una cadena.
seba123neo
2
Si necesita un flotante para mostrárselo al usuario, puede haber algo mal con el diseño de la aplicación. Por lo general, el flotador se usa para calcular y una cadena se usa para mostrarlo al usuario.
n3utrino
lo siento, tienes razón, estaba confundido, solo formatea el número cuando se muestra en la pantalla, no antes, esa fue mi pregunta, muchas gracias, problema resuelto.
seba123neo
1

¡Estaba buscando una respuesta a esta pregunta y luego desarrollé un método! :) Una advertencia justa, está redondeando el valor.

private float limitDigits(float number) {
    return Float.valueOf(String.format(Locale.getDefault(), "%.2f", number));
}
Blogger
fuente