[Précédent]
[Index] | [Corrigé] | [Version imprimable]
[Prochain]

3.12
  Eclipse Tutorial 6 (inutile si vous travaillez avec IntelliJ): Utilisation d'un dévermineur - Enoncé
Niveau 0
 
 
But:
  Vous apprendrez dans ce sixième tutorial à utiliser le dévermineur (debugger) intégré à Eclipse. Certaines options décrites ici ne vous seront utiles que lorsque la notion de méthode aura été abordée. N'hésitez donc pas à revenir à ce document plus tard en cours de semestre.    
Thème:
  Eclipse    
Fichiers:
  Newton.java    

Intégrez le fichier Newton.java dans votre répertoire de travail, par exemple [chemin vers le workspace]/Serie03/src et intégrez-le dans le projet Eclipse correspondant. Le programme Newton.java permet de calculer la racine carrée d'un nombre au moyen de l'algorithme de Newton. Commençons par décrire le fonctionnement de ce petit algorithme. Soit x la racine carrée d'un nombre n. On choisit une valeur comme approximation de départ pour x (1 dans le cas du programme fourni), puis on applique la formule de récurrence suivante :

xk+1 = 1/2 *(xk + n/xk)

Cette formule s'applique, jusqu'à ce que :

Dans le programme fourni, et pour simplifier un peu les choses, c'est le premier type de condition d'arrêt qui est choisi (avec 10 itérations) :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.util.Scanner;

/**
 * Newton
 * 
 * A small utility that computes the square root of a number using newtons algorithm.
 * 
 * The formula for the element x(k + 1) is (1/2)*(x(k) + n/x(k))
 * 
 * Usually, the algorithm is ended after a certain precision is reached or the result
 * changes very little. To keep this example simple, we will stick to a fixed number
 * of iterations (10 in this example).
 */
public class Newton {
    private static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        System.out.println("Please enter the number: ");
        double value = scanner.nextDouble();
        
        //initial value x0 = 1
        double x = 1;
        for (int i = 0; i < 10; i++) {
            //calculate next value
            x = (1/2) * (x + value / x);
        }
        
        System.out.println("The square root of " + value + " is " + x);
    }

}

Lancez le programme et essayez-le pour le nombre 2.0 :

Hum... la valeur calculée est NaN (Not a Number), ce qui est clairement incorrect !

Comme le programme "compile" et qu'aucun message d'erreur n'est généré, nous n'avons, à ce stade, aucune indication sur la source de l'erreur. Il nous faut donc examiner le programme d'un peu plus près pour essayer de localiser le problème : cette tâche ingrate porte des noms parlants tels que "déverminage", "deboggage" (ou "debugging" le plus souvent !).

Une première façon de déverminer consiste à insérer, à des endroits pertinents, du code affichant des informations sur le déroulement du programme et les valeurs des différentes variables (par exemple System.out.println(x)). C'est la méthode que l'on utiliserait si l'on programmait au moyen d'un éditeur de texte basique. Autant dire les choses clairement, c'est en général laborieux; d'autant plus qu'il faut ensuite "nettoyer" le code de toutes instructions "parasites" liées au déverminage.

Seconde option, utiliser un outil dédié à ce genre de tâche : soit un dévermineur (debugger). Ce tutorial a pour but de vous apprendre à utiliser le dévermineur intégré à Eclipse.

Au moyen du bouton droit de la souris, cliquez sur le programme Newton.java dans la vue "Navigator" et choisissez l'option "Debug As -> 1 Java Application".

Le programme va démarrer son exécution, un nombre va vous être demandé et le prosaique NaN de tout à l'heure va à nouveau s'afficher. En fait, tout se passe comme si on avait lancé le programme avec l'option "Run As". Mais pourquoi donc ?

En fait, un dévermineur a besoin d'être informé un minimum de ce que vous souhaitez examiner. En clair, il fonctionne au moyen de "points d'arrêt" (Breakpoints) que vous aurez vous même définis. Les "breakpoints" sont des endroits dans votre programme à partir desquels vous souhaitez arrêter le déroulement normal de l'exécution pour examiner de plus près ce qui se produit. Nous avons donc besoin de définir au moins un "breakpoint".

Comme on ne sait pas trop où l'erreur se situe (et que notre progamme est de petite taille), choisissons de le placer au niveau de la première instruction de notre méthode main. Concrètement : il faut vous placer dans l'éditeur de Eclipse et cliquer au moyen du bouton droit de la souris dans la marge gauche (juste à gauche de la ligne verticale grise). Faites ceci au niveau de de la première instruction de la méthode main. Dans le menu qui apparaîtra alors, sélectionnez l'option "Toggle Breakpoint".

 

Un petit point bleu apparaîtra alors, signalant le point d'arrêt.

Lancez maintenant le programme une nouvelle fois au moyen de l'option "Debug As -> Java Application". Lorsque le point d'arrêt sera atteint, Eclipse vous demandera de basculer vers une perspective "Debug" (note : une perspective est un ensemble de vues cohérentes qui permet de travailler sur un sujet).

Sélectionnez "Remember my decision" et cliquez sur "Yes".

Vous vous trouvez maintenant dans la perspective "Debug"; ce qui devrait ressembler à ceci :

Pour comprendre ce que vous voyez, Il est nécessaire de savoir un minimum de chose sur une des techniques classiques du déverminage , à savoir :

Au milieu de l'écran, vous pouvez voir une fenêtre éditeur dans laquelle une ligne de code est mise en évidence :

Il s'agit de la ligne sur laquelle l'exécution du programme est positionnée.

Vous pouvez maintenant utiliser la barre à outils :

pour contrôler l'exécution de votre programme. Déplacez votre souris sur les différents boutons (en y restant quelques secondes) pour voir les différentes options utilisables. Nous vous décrivons ci-dessous les options les plus importantes. Notez que celles qui sont relatives aux méthodes ne vous seront utiles qu'à partir du cours sur la modularisation, dans deux semaines, si vous suivez la progression du cours. Voici donc les quelques options les plus utiles 

"Resume": permet de quitter le mode "Pas à Pas" et continue l'exécution jusqu'au prochain point d'arrêt.
"Step Into": Si la ligne courante correspond à un appel de méthode, on "entre" dans le corps de cette méthode pour examiner pas à pas son fonctionnement
"Step Over": sauter à la prochaine ligne. Si la ligne courante correspond à un appel de méthode, on exécute l'appel à la méthode sans examiner l'exécution de son corps

Vous pouvez voir, en haut à droite, la vue "Variables" où s'affichent les variables et leurs valeurs dans les différents contextes d'exécution :

Utilisez maintenant le bouton "Step Over" pour poursuivre l'exécution de tout le programme. Gardez un oeil sur la variable x et n'oubliez pas d'entrer une valeur dans la console lorsque le programme vous la demandera (ligne 16).

Vous remarquerez alors que x prend la valeur 0 à la première itération, puis NaN à la suivante. Le calcul :

x = (1/2) * (x + value / x)

retourne donc zéro quand x vaut 1 et value vaut 2.0. Vos connaissances arithmétiques vous dirons que pour qu'une multiplication vaille 0, il faut qu'un moins l'un des opérandes soit nul. Ici :

(1/2) est clairement non-nul,

c'est donc x + value / x qui l'est (... étrange vu que x vaut 1 et value vaut 2 !)

Si nous examinons cette expression, on peut remarquer en fait que la division effectuée est une division entière. Ce qui en effet retourne bien zéro. Nous pouvons corriger ce problème en travaillant avec des valeurs de type double :

Exécutez une nouvelle fois le programme après correction :

cette fois tout fonctionne correctement.

 


[Précédent]
[Index] | [Corrigé] | [Version imprimable]
[Prochain]