web-dev-qa-db-fra.com

Différence entre Math.rint () et Math.round () en Java

Quelle est la différence entre Math.rint() et Math.round()?

11
user2063713

Math.rint() et Math.round() ont plusieurs différences, mais celle qui pourrait avoir le plus d'incidence sur la logique métier d'une application Java est la manière dont elle gère l'arrondi des entiers se trouvant sur une limite (par exemple, 4.5 se trouve sur la limite de 4 et 5). Prenez en compte l'extrait de code et la sortie suivants:

double val1 = 4.2;
double val2 = 4.5;
System.out.println("Math.rint(" + val1 + ")    = " + Math.rint(val1));
System.out.println("Math.round(" + val1 + ")   = " + Math.round(val1));
System.out.println("Math.rint(" + val2 + ")    = " + Math.rint(val2));
System.out.println("Math.round(" + val2 + ")   = " + Math.round(val2));
System.out.println("Math.rint(" + (val2 + 0.001d) + ")  = " + Math.rint(val2 + 0.001d));
System.out.println("Math.round(" + (val2 + 0.001d) + ") = " + Math.round(val2 + 0.001d));

Sortie:

Math.rint(4.2)    = 4.0
Math.round(4.2)   = 4
Math.rint(4.5)    = 4.0
Math.round(4.5)   = 5
Math.rint(4.501)  = 5.0
Math.round(4.501) = 5

Comme vous pouvez le constater, Math.rint(4.5) arrondit en fait, alors que Math.round(4.5) est arrondi, et cela mérite d’être souligné. Cependant, dans tous les autres cas, ils respectent tous les deux les mêmes règles d'arrondi que ce à quoi nous nous attendions.

Voici un article utile de Code Ranch comparant brièvement Math.rint() et Math.round(): http://www.coderanch.com/t/239803/Java-programmer-OCPJP/certification/Difference-rint-methods-Math-class

13
Tim Biegeleisen

Exemple de Math.rint (): 2,50 se situe entre 2,00 et 3,00. Math.rint () renvoie la valeur double même la plus proche. Math.rint (2.50) renvoie 2.0.

Exemple de Math.round (): 2,50 se situe entre 2,00 et 3,00. Math.round () renvoie le nombre entier le plus proche le plus proche. Math.round (2.50) renvoie 3

6
User

Il y a une différence de retour de type:

Math.round() renvoie long ou int
Math.rint() renvoie double

Mais la différence cruciale réside dans le traitement numérique des valeurs entre 0.5.

Math.round() convertit 9.5 <= x < 10.5 en 10
Math.rint() convertit 9.5 <= x <= 10.5 en 10.0

Math.round() convertit 10.5 <= x < 11.5 en 11
Math.rint() convertit 10.5 < x < 11.5 en 11.0

Math.round() convertit 11.5 <= x < 12.5 en 12
Math.rint() convertit 11.5 <= x <= 12.5 en 12.0

(Notez les inégalités!) Donc Math.round() arrondit toujours au milieu (0.5): documentation .
Au lieu de cela, Math.rint() favorise le nombre pair le plus proche du milieu: documentation .

Par exemple, essayez d’exécuter l’exemple trivial suivant:

public class HelloWorld{
    public static void main(String []args){
        System.out.println("Math.round() of 9.5 is " + Math.round(9.5));
        System.out.println("Math.round() of 10.5 is " + Math.round(10.5));
        System.out.println("Math.round() of 11.5 is " + Math.round(11.5));
        System.out.println("Math.round() of 12.5 is " + Math.round(12.5));
        System.out.println("Math.rint() of 9.5 is " + Math.rint(9.5));
        System.out.println("Math.rint() of 10.5 is " + Math.rint(10.5));
        System.out.println("Math.rint() of 11.5 is " + Math.rint(11.5));
        System.out.println("Math.rint() of 12.5 is " + Math.rint(12.5));
    }
}

Notez que la réponse principale actuelle est faux. J'ai essayé de proposer une modification à son message mais il a été rejeté . Donc, selon les commentaires de rejet, je mets mes modifications en tant que nouvelle réponse.

3
Beast257

La différence est à .5

Math.round() convertit [10.5, 11.5[ en 11 
Math.rint() convertit ]10.5, 11.5[ en 11.0 

Math.round() renvoie long ou int.
Math.rint() renvoie le double.

On peut donc dire que Math.round() favorise le point milieu (0.5) pour une valeur plus élevée.

3
Saurav Sahu

Ils se comportent différemment lorsque quelque chose se termine par .5, signé 0, NaN ou un infini.

Math.round accepte à la fois doubles et floats et a des types de retour variables pour une raison quelconque (long et int, respectivement, qui sont le plus petit type suffisamment grand pour couvrir toute la plage représentée par le paramètre).

Math.rint accepte doubles et renvoie doubles. Il est moins "destructeur" que Math.round car il ne modifie pas les valeurs dans plusieurs conditions (voir ci-dessous).

Le comportement de cette méthode est conforme à la norme 4 de la norme IEEE 754, section 4. Ce type d'arrondissement est parfois appelé arrondi au plus proche, ou banquier. Il minimise les erreurs d'arrondi résultant de l'arrondissement constant d'une valeur médiane dans une seule direction.

(Extrait de Réponse de Jon Skeet en C #. Le comportement de Math.Round en C # est plus similaire à celui de Java Math.rint, aussi déroutant soit-il.)


De la docs :

static double rint(double a)

Renvoie la double valeur la plus proche en valeur de l'argument et égale à un entier mathématique.

Renvoie la double valeur la plus proche en valeur de l'argument et égale à un entier mathématique. Si deux valeurs doubles qui sont des nombres entiers mathématiques sont également proches, le résultat est la valeur entière qui est paire. 

Cas spéciaux:

  • Si la valeur de l'argument est déjà égale à un entier mathématique, le résultat est identique à l'argument.

  • Si l'argument est NaN ou un infini ou un zéro positif ou un zéro négatif, le résultat est identique à l'argument.

...

static long round(double a)

...

static int round(float a)

Retourne le plus proche int de l'argument, avec des liens arrondis.

Cas spéciaux:

  • Si l'argument est NaN, le résultat est 0.
  • Si l'argument est l'infini négatif ou toute valeur inférieure ou égale à la valeur de Integer.MIN_VALUE, le résultat est égal à la valeur de Integer.MIN_VALUE.
  • Si l'argument est l'infini positif ou toute valeur supérieure ou égale à la valeur de Integer.MAX_VALUE, le résultat est égal à la valeur de Integer.MAX_VALUE.

Vous pouvez également modifier le comportement de Math.round.

public enum RoundingMode
extends Enum<RoundingMode>

Spécifie un comportement d'arrondi pour les opérations numériques capables de supprimer la précision. Chaque mode d'arrondi indique comment le chiffre retourné le moins significatif d'un résultat arrondi doit être calculé. Si le nombre de chiffres renvoyés est inférieur au nombre nécessaire pour représenter le résultat numérique exact, les chiffres supprimés seront appelés fraction écartée, quelle que soit leur contribution à la valeur du nombre. En d'autres termes, considérée comme une valeur numérique, la fraction écartée pourrait avoir une valeur absolue supérieure à un.

Chaque description du mode d'arrondi comprend un tableau indiquant comment différentes valeurs décimales à deux chiffres seraient arrondies à une valeur décimale à un chiffre dans le mode d'arrondi en question. La colonne de résultat dans les tables peut être obtenue en créant un nombre BigDecimal avec la valeur spécifiée, en formant un objet MathContext avec les paramètres appropriés (précision définie sur 1, et roundingMode défini sur le mode d'arrondi en question), puis en effectuant un round nombre avec le MathContext approprié. Un tableau récapitulatif présentant les résultats de ces opérations d'arrondi pour tous les modes d'arrondi est présenté ci-dessous.

      |  Result of rounding input to one digit with the given rounding 
______ı________________________________________________________________________________________
      |
Input |   UP    DOWN   CEILING    FLOOR    HALF_UP    HALF_DOWN    HALF_EVEN    UNNECESSARY
 5.5  |   6      5        6         5         6           5            6        throw ArithmeticException
 2.5  |   3      2        3         2         3           2            2        throw ArithmeticException
 1.6  |   2      1        2         1         2           2            2        throw ArithmeticException
 1.1  |   2      1        2         1         1           1            1        throw ArithmeticException
 1.0  |   1      1        1         1         1           1            1         1
-1.0  |  -1     -1       -1        -1        -1          -1           -1        -1
-1.1  |  -2     -1       -1        -2        -1          -1           -1        throw ArithmeticException
-1.6  |  -2     -1       -1        -2        -2          -2           -2        throw ArithmeticException
-2.5  |  -3     -2       -2        -3        -3          -2           -2        throw ArithmeticException
-5.5  |  -6     -5       -5        -6        -6          -5           -6        throw ArithmeticException
2
Laurel

Pour les nombres positifs:

si la partie fractionnaire est comprise entre 0 (inclus) et 0,5 (exclusif), alors round () donne la partie entière du nombre.

si la partie fractionnaire est comprise entre 0.5 (inclus) et 1 (exclusif), alors round () donne la partie entière du nombre + 1.

Mais en cas de menthe,

si la partie fractionnaire est comprise entre 0 (inclus) et 0.5 (inclus), alors rint () donne la partie entière du nombre.

si la partie fractionnaire est comprise entre 0.5 (exclusif) et 1 (exclusif), alors round () donne la partie entière du nombre + 1.

Pour un nombre négatif:

Les deux ont le même comportement, c'est-à-dire

si la partie fractionnaire est comprise entre 0 (inclus) et 0,5 (inclus), la partie entière du nombre est renvoyée.

si la fraction décimale est comprise entre 0.5 (inclus) et 1 (exclusif) entier, partie du nombre -1.

la partie fractionnaire est simplement la partie du nombre après décimale

1

En raison du fait que votre question a reçu une réponse importante, je ne passerai pas en revue les points évidents mais je fournirai un article utile que j'ai rencontré:

https://way2Java.com/Java-lang/class-math-Java-lang/difference-of-math-rintdouble-and-math-rounddouble/

Ce que j'ai trouvé de la plus haute importance est le fait que round retourne le nombre entier le plus proche sous la forme d'un entier ou long.

0
Dhruv Erry