Java Language Les opérateurs arithmétiques (+, -, *, /,%)


Exemple

Le langage Java fournit 7 opérateurs effectuant des opérations arithmétiques sur des valeurs entières et à virgule flottante.

  • Il y a deux opérateurs + :
    • L'opérateur d'addition binaire ajoute un numéro à un autre. (Il y a aussi un opérateur binaire + qui effectue la concaténation des chaînes. Ceci est décrit dans un exemple séparé.)
    • L'opérateur unaire plus ne fait rien d'autre que déclencher une promotion numérique (voir ci-dessous)
  • Il y a deux - opérateurs:
    • L'opérateur de soustraction binaire soustrait un nombre d'un autre.
    • L'opérateur moins unaire équivaut à soustraire son opérande de zéro.
  • L'opérateur de multiplication binaire (*) multiplie un nombre par un autre.
  • L'opérateur de division binaire (/) divise un nombre par un autre.
  • L'opérateur binaire reste 1 (%) calcule le reste lorsqu'un nombre est divisé par un autre.

1. Ceci est souvent appelé à tort l'opérateur "module". "Reste" est le terme utilisé par JLS. "Module" et "reste" ne sont pas la même chose.

Opérande et types de résultats, et promotion numérique

Les opérateurs nécessitent des opérandes numériques et produisent des résultats numériques. Les types d'opérandes peuvent être tous les types numériques primitifs ( byte , caractères short , caractères char , int , long , float ou double ) ou tout type d'encapsuleur numérique défini dans java.lang ; à savoir ( Byte , Character , Short , Integer , Long , Float ou Double .

Le type de résultat est déterminé sur la base des types de l'opérande ou des opérandes, comme suit:

  • Si l'un des opérandes est un double ou un Double , le type de résultat est double .
  • Sinon, si l'un des opérandes est un float ou un Float , le type de résultat est float .
  • Sinon, si l'un des opérandes est long ou Long , le type de résultat est long .
  • Sinon, le type de résultat est int . Cela couvre les opérandes byte , short et char ainsi que `int.

Le type de résultat de l'opération détermine comment l'opération arithmétique est effectuée et comment les opérandes sont traités

  • Si le type de résultat est double , les opérandes sont promus pour double , et l'opération est effectuée en utilisant l'arithmétique à virgule flottante IEE 754 64 bits (double précision binaire).
  • Si le type de résultat est float , les opérandes sont promus à float et l'opération est effectuée en utilisant l'arithmétique à virgule flottante IEE 754 32 bits (binaire simple précision).
  • Si le type de résultat est long , les opérandes sont promus à long et l'opération est effectuée en utilisant l'arithmétique d'entier binaire à deux compléments signés 64 bits.
  • Si le type de résultat est int , les opérandes sont promus en int , et l'opération est effectuée en utilisant une arithmétique d'entiers binaires à deux compléments signés 32 bits.

La promotion se déroule en deux étapes:

  • Si le type d'opérande est un type wrapper, la valeur de l'opérande est unboxed à une valeur du type primitif correspondant.
  • Si nécessaire, le type primitif est promu au type requis:
    • La promotion des entiers en int ou en long est sans perte.
    • La promotion du float pour double est sans perte.
    • La promotion d'un entier sur une valeur à virgule flottante peut entraîner une perte de précision. La conversion est effectuée en utilisant la sémantique IEE 768 "round-to-close".

Le sens de la division

L'opérateur / divise l'opérande gauche n (dividende) et l'opérande de droite d (le diviseur) et produit le résultat q (quotient).

La division Java entière arrondit vers zéro. La section JLS 15.17.2 spécifie le comportement de la division entière Java comme suit:

Le quotient produit pour les opérandes n et d est une valeur entière q dont la grandeur est la plus grande possible tout en satisfaisant |d ⋅ q| ≤ |n| . De plus, q est positif quand |n| ≥ |d| et n et d ont le même signe, mais q est négatif lorsque |n| ≥ |d| et n et d ont des signes opposés.

Il y a quelques cas particuliers:

  • Si le n est MIN_VALUE et que le diviseur est -1, alors un dépassement d'entier se produit et le résultat est MIN_VALUE . Aucune exception n'est levée dans ce cas.
  • Si d vaut 0, alors `ArithmeticException est levée.

La division en virgule flottante Java a plus de cas à prendre en compte. Cependant, l'idée de base est que le résultat q est la valeur la plus proche de la satisfaction d . q = n .

La division en virgule flottante ne donnera jamais lieu à une exception. Au lieu de cela, les opérations qui divisent par zéro donnent des valeurs INF et NaN; voir ci-dessous.

La signification du reste

Contrairement à C et C ++, l'opérateur restant en Java fonctionne à la fois avec des opérations à nombre entier et à virgule flottante.

Pour les cas entiers, le résultat d' a % b est défini comme étant le nombre r tel que (a / b) * b + r est égal à a , où / , * et + sont les opérateurs entiers Java appropriés. Cela s'applique dans tous les cas sauf lorsque b est égal à zéro. Ce cas, reste reste une ArithmeticException .

Il résulte de la définition ci-dessus qu'un a % b ne peut être négatif que si a est négatif, et qu'il ne soit positif que si a est positif. De plus, l’ampleur d’ a % b est toujours inférieure à l’ampleur de b .

L'opération de reste à virgule flottante est une généralisation de la casse entière. Le résultat d' a % b est le reste r est défini par la relation mathématique r = a - (b ⋅ q) où:

  • q est un entier,
  • il est négatif uniquement si a / b est négatif et positif uniquement si a / b est positif et
  • sa magnitude est aussi grande que possible sans dépasser l'ampleur du vrai quotient mathématique de a et b .

Le reste à virgule flottante peut produire des valeurs INF et NaN dans les cas limites tels que lorsque b est égal à zéro; voir ci-dessous. Il ne jettera pas une exception.

Note importante:

Le résultat d'une opération de reste à virgule flottante calculée par % n'est pas le même que celui produit par l'opération restante définie par IEEE 754. Le reste de l'IEEE 754 peut être calculé à l'aide de la méthode de bibliothèque Math.IEEEremainder .

Débordement d'entier

Les valeurs entières de Java 32 et 64 bits sont signées et utilisent une représentation binaire en complément à deux. Par exemple, la gamme des nombres représentables comme (32 bits) int -2 31 à 2 31-1.

Lorsque vous ajoutez, soustrayez ou plusieurs deux entiers N bits (N == 32 ou 64), le résultat de l'opération peut être trop important pour représenter un entier N bits. Dans ce cas, l'opération entraîne un débordement d'entier et le résultat peut être calculé comme suit:

  • L'opération mathématique est effectuée pour donner une représentation intermédiaire à deux complément du nombre entier. Cette représentation sera supérieure à N bits.
  • Les 32 ou 64 bits inférieurs de la représentation intermédiaire sont utilisés comme résultat.

Il convient de noter que le débordement d'entier n'entraîne en aucun cas des exceptions.

Valeurs INF et NAN en virgule flottante

Java utilise des représentations à virgule flottante IEE 754 pour float et double . Ces représentations ont des valeurs spéciales pour représenter des valeurs qui ne relèvent pas du domaine des nombres réels:

  • Les valeurs infinies ou INF indiquent des nombres trop importants. La valeur +INF indique des nombres trop grands et positifs. La valeur -INF indique des nombres trop grands et négatifs.
  • Les "indéfinis" / "pas un nombre" ou NaN désignent des valeurs résultant d'opérations sans signification.

Les valeurs INF sont produites par des opérations flottantes qui provoquent un débordement ou par division par zéro.

Les valeurs NaN sont produites en divisant zéro par zéro ou en calculant le reste zéro.

Étonnamment, il est possible d'effectuer des opérations arithmétiques à l'aide des opérandes INF et NaN sans provoquer d'exceptions. Par exemple:

  • Ajouter + INF et une valeur finie donne + INF.
  • Ajouter + INF et + INF donne + INF.
  • Ajouter + INF et -INF donne NaN.
  • La division par INF donne +0.0 ou -0.0.
  • Toutes les opérations avec un ou plusieurs opérandes NaN donnent NaN.

Pour plus de détails, veuillez vous référer aux sous-sections pertinentes de JLS 15 . Notez que c'est largement "académique". Pour les calculs typiques, un INF ou NaN signifie que quelque chose ne va pas; Par exemple, vous avez des données d'entrée incomplètes ou incorrectes, ou le calcul a été programmé de manière incorrecte.