IN3S02: Sujet du TP3
ESIEE Engineering, Denis BUREAU, septembre 2011.

Attention ! Le sujet peut être modifié jusqu'à la veille du TP.

1  Les objectifs

Lire la version PDF de ce sujet et n'utiliser la version web que pour cliquer sur les liens.
Être capable de réaliser sur machine des programmes ne mettant pas en oeuvre des instances. Comprendre l'importance des problèmes de débordement arithmétique et de précision. Savoir utiliser les tests unitaires dans BlueJ.
Attention ! Ce sujet est long, mais les 3 exercices sont faits pour être traités progressivement, ce qui explique les différentes versions, et de nombreux tests sont fournis pour permettre un travail personnel avec une auto-évaluation. Donc, aucune raison de ne pas terminer seul ce TP.

2  Factorielle et problèmes avec les entiers

Charger le projet sujtp3.jar et écrire les méthodes suivantes dans la classe Factorielle. Pour pouvoir tester facilement les méthodes suivantes, déclarez-les toutes en static, afin de ne pas être obligés de créer un objet avant de lancer une méthode.
  1. fact1() :
    Écrivez en Java (dans la classe Factorielle) la fonction factorielle non récursive, mais avec une amélioration : retournez systématiquement -1 si le paramètre est négatif. (Rappel: 0! = 1)
    Essayez 6; ça fait bien 720 ?
  2. monTest() :
    Écrivez en Java (dans la classe Factorielle) une procédure de test qui affiche la factorielle de tous les nombres compris entre ses 2 paramètres, sous la forme 3! = 6 (par exemple, pour la factorielle de 3)
    Questions : Ajoutez dans fact1() un test pour ne pas accepter un paramètre supérieur au maximum trouvé précédemment. Retournez -1 dans ce cas.
  3. Dans la classe FactorielleTest, décommentez la méthode testfact1().
    Compilez; s'il y a des erreurs, corrigez votre code pour qu'il corresponde avec ce qu'attend la classe de test. Run Tests (bouton à gauche). Tout est vert ? Sinon, voir le second encadré ci-dessous.
  4. UTILE POUR L'EXERCICE 4.2.1 : Comment intégrer une classe de test ?
    - Cliquer dans la page web du sujet sur le lien du fichier de test, sélectionner tout, copier.
    - Dans BlueJ, cliquer-droit sur la classe, choisir Create Test Class.
    - Sélectionner tout, coller, compiler.
    - Ne pas modifier la classe de test.

     

     

     

     

  5. Dans BlueJ, en cas d'échec sur un test, cliquez sur la première ligne non "verte", interprétez le message d'erreur, puis cliquez sur le bouton Show Source pour savoir ce qui a été testé. Il peut également être utile d'utiliser le "Code Pad" (menu View) pour essayer interactivement des expressions Java.

     

     

     

  6. fact2() :
    Pour essayer d'aller plus loin que 12!, nous allons utiliser un nouveau type primitif entier qui stocke ses nombres non plus sur 4 mais sur 8 octets (alors pourquoi pas le type double ?) : le mot java est long.
    Dupliquez la méthode fact1() (dans la classe Factorielle) en la changeant de nom, et remplacez uniquement là où il le faut int par long. Les constantes littérales se terminent par L (ex: -1L).
    Pensez-vous que fact2() pourra calculer jusqu'à 100, 1000, plus ?
    Soyons raisonnables : ayant doublé le nombre d'octets, nous supposerons dans un premier temps que le maximum ne peut pas plus que doubler. Modifiez-le dans fact2().
  7. monTest2() :
    Recopiez la procédure monTest() et modifiez-la pour qu'elle appelle fact2() au lieu de fact1().
    Questions :
  8. Dans la classe FactorielleTest, décommentez la 2ème méthode, recompilez, et exécutez les tests.
    Tout est vert ? Passez au 3.
  9. A NE PAS COMMENCER EN TP : A TERMINER EN TRAVAIL PERSONNEL  fact3() :
    Pour essayer d'aller plus loin que 20!, nous allons utiliser un nouveau type entier (objet) qui stocke ses nombres non plus sur 4 ou sur 8 octets, mais dans une String de longueur pratiquement illimitée : le nom de cette classe est BigInteger.
    Dupliquez la méthode fact2() (dans la classe Factorielle) en la changeant de nom, et remplacez les long par des BigInteger.
    Il va falloir faire un certain nombre de modifications car nous remplaçons un type primitif par un type objet :
    - repérez le paquetage de BigInteger (voir javadoc); cela servira pour la compilation
    - utilisez le BigInteger de valeur 1 (voir javadoc)
    - utilisez la bonne méthode pour prendre l'opposé (voir javadoc)
    - utilisez la bonne méthode pour convertir un int en BigInteger (voir javadoc, sachant qu'un int est automatiquement converti en long si nécessaire)
    - utilisez la bonne méthode pour multiplier (voir javadoc)
    Pensez-vous que fact3() pourra calculer jusqu'à 100, 1000, plus ?
    Soyons déraisonnables : supprimons la borne supérieure du test dans fact3() et découvrons des factorielles rarement calculées.
  10. monTest3() :
    Recopiez la procédure monTest2() et modifiez-la pour qu'elle appelle fact3() au lieu de fact2().
    Questions :
  11. Dans la classe FactorielleTest, décommentez la 3ème méthode, recompilez, et exécutez les tests.
    Tout est vert ?

3  Racine carrée et problèmes avec les réels

       (D'après un exercice de Jean-Claude GEORGES) Affichez le sujet en PDF (version imprimable)
  1. racine1() :
    Écrivez en Java (dans la classe RacineNewton) une fonction qui calcule la racine carrée d'un nombre positif (sans utiliser Math.sqrt()) selon l'algorithme de Newton, c'est-à-dire : si on suppose que r est une valeur approchée (même mauvaise) de a, alors Newton a montré que [1/2](r+[a/r]) est une meilleure valeur approchée. On peut donc en théorie se rapprocher aussi près que l'on veut de la valeur "exacte" de la racine carrée ; essayons de le vérifier à e près : on définira e en CONSTANTE (égale à 10-6 par exemple) et on arrêtera la boucle lorsque l'écart entre r2 et a sera inférieur à e.
    Pour cela, on définira une fonction booléenne environ1() qui comparera ses 2 paramètres réels x et y à e près (|x-y| < e ?) et on utilisera environ1(x,y) au lieu de x == y.
    AIDE : Toute valeur initiale est possible pour r, par exemple [a/2] ou 1 ou ...
  2. Testez votre fonction avec au moins les valeurs suivantes en plus de décommenter la procédure RacineNewtonTest.testracine1() et d'exécuter les tests :
    1E-6 : ça fait bien 0.001000 ? Pourquoi ?
    1E-20 : ça fait bien 1E-10 ? Pourquoi ?
    1E11 : ça fait bien 316227.766017 ? Pourquoi ? (oscillations ?)
  3. racine2() :
    Compte tenu des problèmes précédents, écrivez une nouvelle fonction qui appellera une nouvelle fonction booléenne environ2() qui tiendra compte de l'ordre de grandeur de x ou y pour comparer ses 2 paramètres réels x et y à e près (|[(x-y)/x]| < e ? si x n'est pas trop proche de 0).
    On considérera que x est assimilable à 0 si |x| < 10-300 ; dans ce cas, x = 0.0.
    D'autre part, si l'un est proche de 0 et l'autre pas, retourner directement faux !
  4. Décommentez la procédure RacineNewtonTest.testracine2() et exécutez les tests. Est-ce correct pour les 3 valeurs problématiques ci-dessus ?

4  Projet "Lines" (A COMMENCER EN TP ET A TERMINER EN TRAVAIL PERSONNEL)

Cet exercice va consister à créer une nouvelle classe, indépendante, permettant de représenter une droite dans le plan, puis à comparer 2 droites.
Rappels mathématiques :
- 2 droites sont orthogonales si le produit scalaire des vecteurs directeurs est nul (aa¢+bb¢=0)
- 2 droites sont colinéaires si elles ont le même coefficient directeur (-[b/a] = -[(b¢)/(a¢)] si a ¹ 0 et a¢ ¹ 0)
- 2 droites peuvent être confondues sans avoir nécessairement a=a¢ et b=b¢ et c=c¢
- [(x1)/(y1)] = [(x2)/(y2)] Û x1y2 = x2y1

4.1  Créer un nouveau projet

Créer dans le répertoire tp3, préalablement créé,  un nouveau projet BlueJ de nom Lines.

4.2  Créer une nouvelle classe

Définir une classe Line, en la documentant au fur et à mesure, répondant aux spécifications suivantes :

4.2.1  Version 1

4.2.2  Version 2

4.2.3  Version 3

4.2.4  Version 4

4.2.5  Version 5

4.2.6  Version graphique optionnelle




File translated from TEX by TTH, version 3.74.
On 29 Sep 2011, 01:04.