¿Cuál es la mejor práctica para redondear un flotante a 2 decimales?

Estoy usando eclipse + Android SDK.

Necesito redondear un valor flotante a 2 decimales. Usualmente uso el siguiente “truco” usando la biblioteca Math.

float accelerometerX = accelerometerX * 100; accelerometerX = round(accelerometerX); Log.d("Test","" + accelerometerX/100); 

Pero siento que no es la mejor manera de hacerlo.

¿Hay una biblioteca para hacer este tipo de operaciones?

Gracias por adelantado.

Estuve trabajando con estadísticas en Java hace 2 años y todavía tengo los códigos de una función que le permite redondear un número al número de decimales que desea. Ahora necesita dos, pero tal vez le gustaría probar con 3 para comparar resultados, y esta función le otorga esta libertad.

  /** * Round to certain number of decimals * * @param d * @param decimalPlace * @return */ public static float round(float d, int decimalPlace) { BigDecimal bd = new BigDecimal(Float.toString(d)); bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP); return bd.floatValue(); } 

Debe decidir si desea redondear hacia arriba o hacia abajo. En mi código de muestra estoy redondeando.

Espero eso ayude.

EDITAR

Si desea conservar el número de decimales cuando son cero (supongo que es solo para mostrar al usuario) solo tiene que cambiar el tipo de función de float a BigDecimal, así:

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

Y luego llame a la función de esta manera:

  float x = 2.3f; BigDecimal result; result=round(x,2); System.out.println(result); 

Esto se imprimirá:

 2.30 

Probemos 3 métodos:
1)

 public static double round1(double value, int scale) { return Math.round(value * Math.pow(10, scale)) / Math.pow(10, scale); } 

2)

 public static float round2(float number, int scale) { int pow = 10; for (int i = 1; i < scale; i++) pow *= 10; float tmp = number * pow; return ( (float) ( (int) ((tmp - (int) tmp) >= 0.5f ? tmp + 1 : tmp) ) ) / pow; } 

3)

 public static float round3(float d, int decimalPlace) { return BigDecimal.valueOf(d).setScale(decimalPlace, BigDecimal.ROUND_HALF_UP).floatValue(); } 

El número es 0.23453f
Probaremos 100.000 iteraciones de cada método.

Resultados:
Tiempo 1 – 18 ms
Tiempo 2 – 1 ms
Tiempo 3 – 378 ms

Probado en la computadora portátil
Intel i3-3310M CPU 2.4GHz

 double roundTwoDecimals(double d) { DecimalFormat twoDForm = new DecimalFormat("#.##"); return Double.valueOf(twoDForm.format(d)); } 

Aquí hay una implementación más corta en comparación con @ Jav_Rock’s

  /** * Round to certain number of decimals * * @param d * @param decimalPlace the numbers of decimals * @return */ public static float round(float d, int decimalPlace) { return BigDecimal.valueOf(d).setScale(decimalPlace,BigDecimal.ROUND_HALF_UP).floatValue(); } System.out.println(round(2.345f,2));//two decimal digits, //2.35 

Intenté apoyar los valores -ve para el excelente segundo método de @Ivan Stin. (El mayor crédito es para @Ivan Stin por su método)

 public static float round(float value, int scale) { int pow = 10; for (int i = 1; i < scale; i++) { pow *= 10; } float tmp = value * pow; float tmpSub = tmp - (int) tmp; return ( (float) ( (int) ( value >= 0 ? (tmpSub >= 0.5f ? tmp + 1 : tmp) : (tmpSub >= -0.5f ? tmp : tmp - 1) ) ) ) / pow; // Below will only handles +ve values // return ( (float) ( (int) ((tmp - (int) tmp) >= 0.5f ? tmp + 1 : tmp) ) ) / pow; } 

A continuación se encuentran los casos de prueba que probé. Por favor, avíseme si esto no está abordando ningún otro caso.

 @Test public void testFloatRound() { // +ve values Assert.assertEquals(0F, NumberUtils.round(0F), 0); Assert.assertEquals(1F, NumberUtils.round(1F), 0); Assert.assertEquals(23.46F, NumberUtils.round(23.4567F), 0); Assert.assertEquals(23.45F, NumberUtils.round(23.4547F), 0D); Assert.assertEquals(1.00F, NumberUtils.round(0.49999999999999994F + 0.5F), 0); Assert.assertEquals(123.12F, NumberUtils.round(123.123F), 0); Assert.assertEquals(0.12F, NumberUtils.round(0.123F), 0); Assert.assertEquals(0.55F, NumberUtils.round(0.55F), 0); Assert.assertEquals(0.55F, NumberUtils.round(0.554F), 0); Assert.assertEquals(0.56F, NumberUtils.round(0.556F), 0); Assert.assertEquals(123.13F, NumberUtils.round(123.126F), 0); Assert.assertEquals(123.15F, NumberUtils.round(123.15F), 0); Assert.assertEquals(123.17F, NumberUtils.round(123.1666F), 0); Assert.assertEquals(123.46F, NumberUtils.round(123.4567F), 0); Assert.assertEquals(123.87F, NumberUtils.round(123.8711F), 0); Assert.assertEquals(123.15F, NumberUtils.round(123.15123F), 0); Assert.assertEquals(123.89F, NumberUtils.round(123.8909F), 0); Assert.assertEquals(124.00F, NumberUtils.round(123.9999F), 0); Assert.assertEquals(123.70F, NumberUtils.round(123.7F), 0); Assert.assertEquals(123.56F, NumberUtils.round(123.555F), 0); Assert.assertEquals(123.00F, NumberUtils.round(123.00F), 0); Assert.assertEquals(123.50F, NumberUtils.round(123.50F), 0); Assert.assertEquals(123.93F, NumberUtils.round(123.93F), 0); Assert.assertEquals(123.93F, NumberUtils.round(123.9312F), 0); Assert.assertEquals(123.94F, NumberUtils.round(123.9351F), 0); Assert.assertEquals(123.94F, NumberUtils.round(123.9350F), 0); Assert.assertEquals(123.94F, NumberUtils.round(123.93501F), 0); Assert.assertEquals(99.99F, NumberUtils.round(99.99F), 0); Assert.assertEquals(100.00F, NumberUtils.round(99.999F), 0); Assert.assertEquals(100.00F, NumberUtils.round(99.9999F), 0); // -ve values Assert.assertEquals(-123.94F, NumberUtils.round(-123.93501F), 0); Assert.assertEquals(-123.00F, NumberUtils.round(-123.001F), 0); Assert.assertEquals(-0.94F, NumberUtils.round(-0.93501F), 0); Assert.assertEquals(-1F, NumberUtils.round(-1F), 0); Assert.assertEquals(-0.50F, NumberUtils.round(-0.50F), 0); Assert.assertEquals(-0.55F, NumberUtils.round(-0.55F), 0); Assert.assertEquals(-0.55F, NumberUtils.round(-0.554F), 0); Assert.assertEquals(-0.56F, NumberUtils.round(-0.556F), 0); Assert.assertEquals(-0.12F, NumberUtils.round(-0.1234F), 0); Assert.assertEquals(-0.12F, NumberUtils.round(-0.123456789F), 0); Assert.assertEquals(-0.13F, NumberUtils.round(-0.129F), 0); Assert.assertEquals(-99.99F, NumberUtils.round(-99.99F), 0); Assert.assertEquals(-100.00F, NumberUtils.round(-99.999F), 0); Assert.assertEquals(-100.00F, NumberUtils.round(-99.9999F), 0); } 

Aquí hay una solución simple de una línea

 ((int) ((value + 0.005f) * 100)) / 100f 
 //by importing Decimal format we can do... import java.util.Scanner; import java.text.DecimalFormat; public class Average { public static void main(String[] args) { int sub1,sub2,sub3,total; Scanner in = new Scanner(System.in); System.out.print("Enter Subject 1 Marks : "); sub1 = in.nextInt(); System.out.print("Enter Subject 2 Marks : "); sub2 = in.nextInt(); System.out.print("Enter Subject 3 Marks : "); sub3 = in.nextInt(); total = sub1 + sub2 + sub3; System.out.println("Total Marks of Subjects = " + total); res = (float)total; average = res/3; System.out.println("Before Rounding Decimal.. Average = " +average +"%"); DecimalFormat df = new DecimalFormat("###.##"); System.out.println("After Rounding Decimal.. Average = " +df.format(average)+"%"); } } /* Output Enter Subject 1 Marks : 72 Enter Subject 2 Marks : 42 Enter Subject 3 Marks : 52 Total Marks of Subjects = 166 Before Rounding Decimal.. Average = 55.333332% After Rounding Decimal.. Average = 55.33% */ /* Output Enter Subject 1 Marks : 98 Enter Subject 2 Marks : 88 Enter Subject 3 Marks : 78 Total Marks of Subjects = 264 Before Rounding Decimal.. Average = 88.0% After Rounding Decimal.. Average = 88% */ /* You can Find Avrerage values in two ouputs before rounding average And After rounding Average..*/