Priorités des opérateurs arithmétiques et parallélles
Éliminer les parenthèses superflues dans les expressions suivantes (l’ordre des calculs devant rester le même) : (a + b) – (2 * c) // expression 1 (2 * x) / (y * z) // expression 2 (x + 3) * (n%p) // expression 3 (-a) / (-(b + c)) // expression 4 (x/y)%(-z) // expression 5 x/(y%(-z)) // expression 6 a + b – 2 * c // expression 1 2 * x / (y * z) // expression 2 On pourrait aussi écrire cette expression 2*x/y/z mais l’ordre des calculs sera différent, ce qui peut avoir une légère incidence sur le résultat. (x + 3) * (n%p) // expression 3 Ici aucune parenthèse ne peut être supprimée car * et % sont de même priorité ; la suppression de la seconde paire de parenthèses conduirait à une expression équivalent à : ((x+3)*n)%p. -a / -(b + c) // expression 4 Ne pas oublier que l’opérateur unaire – est prioritaire sur tous les opérateurs arithmétiques à deux opérandes. x/y%-z // expression 5 x/(y%-z) // expression 6 Conversions implicites Éliminer les parenthèses superflues dans les expressions suivantes (l’ordre des calculs devant rester le même) : (a + b) – (2 * c) // expression 1 (2 * x) / (y * z) // expression 2 (x + 3) * (n%p) // expression 3 (-a) / (-(b + c)) // expression 4 (x/y)%(-z) // expression 5 x/(y%(-z)) // expression 6 Soit ces déclarations : byte b1 = 10, b2 = 20 ; short p = 200 ; int n = 500 ; long q = 100 ; float x = 2.5f ; double y = 5.25 ;
Exercice 2 Conversions implicites
b1+b2 = 30 // 1 L’opérateur + soumet les valeurs de b1 et b2 à la promotion numérique de byte en int. Le résutat est de type int. p+b1 = 210 // 2 L’opérateur + soumet ses opérandes à des promotions numériques : de short en int pour p et de byte en int pour b1. Le résultat est de type int. b1*b2 = 200 // 3 Là encore, avant d’effectuer le produit, les valeurs de b1 et de b2 sont soumises à la promotion numérique de byte en int. Le résultat est de type int. q+p*(b1+b2) = 6100 // 4 On évalue tout d’abord la somme s=b1+b2, en soumettant les valeurs des deux opérandes aux promotions numériques de byte en int. La valeur de s est de type int. Puis on effectue la somme q+p en soumettant le second opérande à une conversion d’ajustement de type de short en long (type de q). Le résultat est de type long. Il faut maintenant le multiplier par s, ce qui se fait en soumettant la valeur de s à une conversion d’ajustement de type de int en long. Le résultat final est de type long. x+q*n =50002.5 // 5 On évalue tout d’abord le produit q*n en soumettant la valeur de n à une conversion d’ajustement de type de int en long. Le résultat est de type long. Pour pouvoir l’ajouter à la valeur de x, on le soumet à une conversion d’ajustement de type de long en float. Le résultat est de type float. b1*q/x=400.0 // 6 On évalue tout d’abord le quotient q/x en soumettant la valeur de q à une conversion d’ajustement de type de long en float. Le résultat est de type float. Pour pouvoir lui ajouter la valeur de b1, on soumet cette dernière à une conversion d’ajustement de type de byte en float (ou, ce qui revient au même, d’abord à une promotion numérique de byte en int, puis à une conversion d’ajustement de type de int en float). Le résultat est de type float. b1*q*2./x=800.0 // 7 Donner le type et la valeur des expressions arithmétiques suivantes : b1+b2 // 1 p+b1 // 2 b1*b2 // 3 q+p*(b1+b2); // 4 x+q*n // 5 b1*q/x // 6 b1*q*2./x // 7 b1*q*2.f/x // 8 geneli~1.book Page 3 Lundi, 10. juillet 2006 12:46 12 Les opérateurs et les expressions Chapitre 1 4 © Éditions Eyrolles On évalue tout d’abord le produit q*2., en soumettant la valeur de q à une conversion d’ajustement de type de long en double (attention, la constante 2. est de type double et non de type float). Le résultat est de type double. Il est divisé par la valeur obtenue par conversion d’ajustement de type de x de float en double. Le résultat, de type double est alors multiplié par la valeur obtenue par conversion d’ajustement de type de b1 en double. Le résultat est de type double. b1*q*2.f/x=800.0 // 8 Il s’agit de l’expression précédente, dans laquelle la constante 2. (de type double) est remplacée par 2.f de type float. La même démarche s’applique, en substituant le type float au type double. Le résultat final est de type float.
Exceptions flottantes et conventions IEEE
Quels résultats fournit ce programme ? public class Excep { public static void main (String args[]) { double x1 = 1e200, x2 = 1e210 ; double y, z ; y = x1*x2 ; System.out.println (« valeur de y » + y) ; x2 = x1 ; z = y/(x2-x1) ; System.out.println (y + » divise par » + (x2-x1) + » = » + z) ; y = 15 ; z = y/(x2-x1) ; System.out.println (y + » divise par » + (x2-x1) + » = » + z) ; z = (x2-x1)/(x2-x1) ; System.out.println ((x2-x1) + » divise par » + (x2-x1) + » = » + z) ; System.out.println (z + « +1 = » + (z+1)) ; x1 = Float.POSITIVE_INFINITY ; x2 = Double.NEGATIVE_INFINITY ; z = x1/x2 ; System.out.println (x1 + « / » + x2 + » = » + z) ; } }
Exercice 4
Le type char Infinity divise par 0.0 = Infinity 15.0 divise par 0.0 = Infinity 0.0 divise par 0.0 = NaN NaN+1 = NaN Infinity/-Infinity = NaN Rappelons qu’en Java aucune opération sur les flottants ne conduit à un arrêt de l’exécution. En revanche, les nombres flottants respectent les conventions IEEE 754 qui imposent l’existence d’un motif particulier représentant les valeurs infinies, lequel s’imprime sous la forme Infinity ou -Infinity. Les constantes correspondantes se notent Float.Infinity ou Double.Infinity. De même, il existe un motif particulier représentant une valeur non calculable ; il peut s’obtenir par Float.NaN ou Double.NaN et il s’imprime sous la forme NaN. Le type char c + 1 = 61 L’opérateur + soumet ici son premier opérande à la promotion numérique de char en int, ce qui fournit la valeur 601. Le résultat est de type int. 2 * c = 120 L’opérateur * soumet ici son second opérande à la promotion numérique de char en int, ce qui fournit la valeur 602. Le résultat est de type int. cg – ce = 2 L’opérateur – soumet ici ses deux opérandes à la promotion numérique de char en int. On obtient un résultat de type int qui représente l’écart entre les codes des caractères g et e (dans le code Unicode, les lettres consécutives d’une même casse ont des codes consécutifs).