116 votes

Quelle est la meilleure pratique pour arrondir un flottant à deux décimales ?

J'utilise eclipse + Android SDK.

Je dois arrondir une valeur flottante à deux décimales. J'utilise généralement le "truc" suivant en utilisant la bibliothèque Math.

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

Mais je pense que ce n'est pas la meilleure façon de procéder.

Existe-t-il une bibliothèque pour effectuer ce type d'opérations ?

4 votes

Vous pouvez jeter un coup d'œil à cette question : stackoverflow.com/questions/153724/

1 votes

Ou vous pouvez trouver le nombre après la décimale, le convertir en int, et faire un décalage de bit à droite. En gros, c'est ce que ferait un rond.

172voto

Jav_Rock Points 12621

Je travaillais sur les statistiques en Java il y a 2 ans et j'ai encore les codes d'une fonction qui permet d'arrondir un nombre au nombre de décimales que l'on souhaite. Maintenant, vous en avez besoin de deux, mais peut-être aimeriez-vous essayer avec 3 pour comparer les résultats, et cette fonction vous donne cette 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();
}

Vous devez décider si vous voulez arrondir vers le haut ou vers le bas. Dans mon exemple de code, j'arrondis vers le haut.

J'espère que cela vous aidera.

EDITAR

Si vous voulez conserver le nombre de décimales lorsqu'elles sont nulles (je suppose que c'est juste pour l'affichage à l'utilisateur), il suffit de changer le type de fonction de float à BigDecimal, comme ceci :

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

Et ensuite, appelez la fonction de cette façon :

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

Cela va s'imprimer :

2.30

2 votes

Mais maintenant, le flotteur n'affiche qu'une seule décimale si la seconde est 0. Savez-vous comment afficher toujours le signe et toutes les (2) décimales ? Exemple : 2.1234 --> 2.12 mais 2.1 --> 2.1 mais pas 2.10

1 votes

Comment arrondir à deux décimales dans Android ?

0 votes

J'aime faire court. new BigDecimal(String.valueOf(double)).setScale(yourScale, BigDecimal.ROUND_HALF_UP);

55voto

Ivan Stin Points 685

Testons 3 méthodes :
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();
}

Le nombre est 0.23453f
Nous testerons 100 000 itérations pour chaque méthode.

Résultats :
Temps 1 - 18 ms
Temps 2 - 1 ms
Temps 3 - 378 ms

Testé sur un ordinateur portable
CPU Intel i3-3310M 2.4GHz

35voto

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

2 votes

J'essaye d'utiliser cette fonction avec float, mais les exceptions sont jetées.

0 votes

La méthode est conçue pour les Doubles. J'ai ajouté la même fonction pour les Floats.

3 votes

Cela fonctionne pour moi vous devez changer comme ceci float roundTwoDecimals(float d) { DecimalFormat twoDForm = new DecimalFormat("#.##") ; return Float.valueOf(twoDForm.format(d)) ; }

15voto

Jaskey Points 368

Voici une implémentation plus courte comparée à celle de @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

9voto

manikanta Points 2184

J'ai essayé de soutenir les valeurs -ve pour l'excellente 2ème méthode de @Ivan Stin. (Le crédit majeur revient à @Ivan Stin pour sa méthode)

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

Voici les cas de tests que j'ai essayés. Veuillez me faire savoir si cela ne répond pas à d'autres cas.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X