UNIVERSITÉ BORDEAUX I Département premier cycle Sciences
Juin 1995
Polycopié, notes de cours et de TD autorisés.
Autres documents interdits.
Les 3 exercices sont indépendants ; donner des réponses simples et précises : les fonctions C demandées sont très courtes (quelques lignes). Ecrire des généralités, ou copier des fonctions vues en cours ou en TD, vous fera perdre du temps sans vous rapporter aucun point.
|
typedef int nombre [MAX];Veiller, dans tous les cas, à la qualité des en-têtes de fonctions.
Note : ici, comme dans le reste de l'exercice, on ne demande aucune conversion d'une base dans une autre.
Comment proposez-vous de traiter le cas où le nombre de chiffres de x+y dépasse MAX ?
struct complexe {double reel, imaginaire; };et on dispose des fonctions :
struct complexe somme (struct complexe u, struct complexe v); struct complexe produit (struct complexe u, struct complexe v); double module (struct complexe z);Soit f la fonction définie par f(z) = z2+c , où c désigne une constante complexe, et soit zn la suite définie par la récurrence :
|
Note : veiller à bien spécifier les paramètres de cette fonction.
void decompose (long n) { long d; for (d = 2; d * d <= n;) if (n % d == 0) { printf (" %d", d); n = n / d; } else d++; printf (" %d\n", n); }Par exemple, si n = 200, cette fonction affiche : 2 2 2 5 5.
Modifier cette fonction pour qu'elle affiche chaque facteur avec sa multiplicité ; par exemple, si n = 200, la fonction modifiée affiche : 2 puissance 3, 5 puissance 2.
void afficher (nombre x) { int i, j; for (i = MAX - 1; i > 0 && x [i] == 0; i--); for (j = i; j >= 0; j--) printf ("%d", x [j]); printf ("\n"); }
Variantes et remarques :
void afficher (int *x) ou : void afficher (int x [])
for (; i >= 0; i--) printf ("%d", x [i]);
void somme (nombre z, nombre x, nombre y, int base) { int i, retenue = 0; for (i = 0; i < MAX; i++) { z [i] = x [i] + y [i] + retenue; if (z [i] >= base) { retenue = 1; z [i] = z [i] - base; } else retenue = 0; } }
Noter que la base est un paramètre de cette fonction, car il est impossible d'additionner x et y sans connaître la base utilisée.
Le nombre de chiffres de x+y dépasse MAX si et seulement si la fonction se termine avec retenue = 1. Le moyen le plus simple de le signaler à l'utilisateur (qui en fera ce qu'il voudra), est de transformer cette fonction en une fonction booléenne : remplacer void par int dans l'en-tête, et ajouter
return retenue;
à la fin (2 points).
Remarque : certains étudiants n'ont pas utilisé de variable retenue , et ont écrit :
for (i = 0; i < MAX; i++) { z [i] = x [i] + y [i] + z [i]; if (z [i] >= base) { z [i + 1] = 1; z [i] = z [i] - base; } else z [i + 1] = 0; }Mais cette solution est fausse pour la première et la dernière valeur de i : z [0] n'est pas initialisé, et surtout z [MAX] n'existe pas.
struct complexe f (struct complexe z, struct complexe c) { return somme ( produit (z, z), c ); }
int disque (struct complexe z, struct complexe c, int n, double r) { int i; for (i = 1; i <= n; i++) z = f (z, c); return ( module (z) <= r ); }
La variante suivante est évidemment correcte, mais peu élégante :
if ( module (z) <= r ) return 1; else return 0;
void decompose (long n) { long d; int multiplicite; for (d = 2; d * d <= n; d++) { multiplicite = 0; while (n % d == 0) { multiplicite++; n = n / d; } if (multiplicite > 0) printf ("%d puissance %d, ", d, multiplicite); } if (n > 1) printf ("%d", n); printf ("\n"); }Ne pas oublier if (multiplicite > 0) avant printf. La solution voisine :
int multiplicite = 0; for (d = 2; d * d <= n;) { if (n % d == 0) { multiplicite++; n = n / d; } else { if (multiplicite > 0) printf ("%d puissance %d, ", d, multiplicite); multiplicite = 0; d++; } }a été considérée comme correcte, mais en fait elle pose des problèmes délicats quand on sort de la boucle : le dernier diviseur d a-t-il bien été affiché, et sinon est-il égal à n ?