Qual è la migliore pratica per arrotondare un float a 2 decimali?

Sto usando eclipse + Android SDK.

Devo arrotondare un valore float a 2 decimali. Di solito uso il prossimo “trucco” usando la libreria Math.

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

Ma sento che non è il modo migliore per farlo.

C’è una biblioteca per fare questo tipo di operazioni?

Grazie in anticipo.

Stavo lavorando con le statistiche in Java 2 anni fa e ho ancora i codici di una funzione che ti permette di arrotondare un numero al numero di decimali che vuoi. Ora ne hai bisogno di due, ma forse ti piacerebbe provare con 3 per confrontare i risultati, e questa funzione ti dà questa libertà.

  /** * 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(); } 

Devi decidere se vuoi arrotondare per eccesso o per difetto. Nel mio codice di esempio sto arrotondando.

Spero che sia d’aiuto.

MODIFICARE

Se vuoi conservare il numero di decimali quando sono zero (suppongo che sia solo per la visualizzazione all’utente) devi solo cambiare il tipo di funzione da float a BigDecimal, come questo:

 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; } 

E quindi chiama la funzione in questo modo:

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

Questo stamperà:

 2.30 

Proviamo 3 metodi:
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(); } 

Il numero è 0.23453f
Testeremo 100.000 iterazioni per ciascun metodo.

risultati:
Tempo 1 – 18 ms
Tempo 2 – 1 ms
Tempo 3 – 378 ms

Testato sul laptop
CPU Intel i3-3310M a 2,4 GHz

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

Ecco un’implementazione più breve rispetto a @ Jav_Rock

  /** * 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 

Ho provato a supportare i valori -ve per il secondo metodo di @Ivan Stin. (Il merito principale va a @Ivan Stin per il suo metodo)

 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; } 

Di seguito sono riportati i casi di test che ho provato. Per favore fatemi sapere se questo non sta affrontando altri casi.

 @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); } 

Ecco una semplice soluzione a una linea

 ((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..*/