Avant de commencer5 questions pour vérifier tes bases
Comprendre ce que fait un programme
Un algorithme décrit une suite d'instructions. Python permet de l'exécuter, mais l'ordinateur ne connaît ni la question du cours ni les hypothèses d'un théorème. Un nombre affiché ne dit pas, à lui seul, si c'est une valeur exacte, une approximation contrôlée ou une simulation.
Python : des instructions que l'on peut suivre
Affectation : lire la droite avant de changer la gauche
x = 3
y = x + 2
x = 10
y = y + x
print(x, y)
| Instruction exécutée | x | y |
|---|---|---|
| \(\texttt{x = 3}\) | 3 | non défini |
| \(\texttt{y = x + 2}\) | 3 | 5 |
| \(\texttt{x = 10}\) | 10 | 5 |
| \(\texttt{y = y + x}\) | 10 | 15 |
y ne reste pas une formule liée à x : son calcul a déjà eu lieu. L'affichage est donc 10 15.
Types, calculs et nombres approchés
int | Entier, par exemple -3 ou 1000. Les opérations entières usuelles sont exactes, dans les limites de mémoire. |
|---|---|
float | Nombre à virgule flottante, par exemple 0.1. C'est une approximation binaire de précision finie, pas un réel exact quelconque. |
bool | True ou False, résultat d'un test. |
str | Texte, par exemple "bonjour". |
list | Liste ordonnée de valeurs, par exemple [2, 5, 8]. |
print(7 / 2) # 3.5 : quotient
print(7 // 2) # 3 : quotient entier arrondi vers le bas
print(7 % 2) # 1 : reste
print(-7 // 2) # -4, car -7 = 2*(-4) + 1
print(2**3) # 8 : puissance, pas 2^3
print(0.1 + 0.2) # 0.30000000000000004
Entrées, affichages, imports et exécution
Dans un environnement Python, on peut exécuter des instructions dans une console ou enregistrer un script. Les blocs ci-dessous se lisent de haut en bas. Une fonction définie dans le cours doit être exécutée avant les exemples qui l'appellent ; les imports indiqués doivent aussi avoir été exécutés. Les blocs sont des exemples distincts, pas un unique script à lancer aveuglément.
texte = input("Entier positif ou nul : ")
n = int(texte)
print("Son carré vaut", n**2)
from math import sqrt, exp, log, sin, cos, pi
print(sqrt(2))
print(log(exp(1)))
input renvoie un texte ; int le convertit si son écriture représente un entier. Un texte comme "trois" produit une erreur de conversion. Les fonctions mathématiques gardent leurs domaines : log(x) exige \(x>0\), sqrt(x) exige \(x\geqslant0\) pour un résultat réel. Les angles de sin et cos sont en radians.
Tests et choix : comprendre quelle branche est exécutée
temperature = 0
if temperature < 0:
print("Température négative")
elif temperature == 0:
print("Température nulle")
else:
print("Température positive")
Une chaîne if/elif/else n'exécute qu'une branche : la première dont le test est vrai, ou le else si aucune ne convient. Les deux-points ouvrent un bloc. L'indentation en délimite les instructions ; utiliser quatre espaces par niveau et éviter de mélanger tabulations et espaces.
Boucle for : parcourir sans oublier la borne exclue
print(list(range(2, 7, 2))) # [2, 4, 6]
print(list(range(5, 0, -2))) # [5, 3, 1]
S = 0
for k in range(1, 5):
S = S + k**2
print(S) # 30
La boucle additionne quatre termes. L'accumulateur part de 0, élément neutre de l'addition. Après \(k=1,2,3,4\), ses valeurs sont respectivement \(1,5,14,30\). Déplacer S = 0 dans la boucle effacerait les sommes précédentes.
Fonctions : séparer le calcul de son affichage
def carre(x):
resultat = x**2
return resultat
y = carre(3) + 1
print(y) # 10
Exécuter def définit la fonction et son nom. Son corps s'exécute lorsqu'on l'appelle, ici avec \(x=3\). return renvoie une valeur à l'appelant et quitte la fonction. print affiche, sans fournir à sa place une valeur numérique réutilisable. Une fonction qui termine sans return renvoie None.
def pente_secante(f, x, h):
if h == 0:
raise ValueError("h doit être non nul")
return (f(x + h) - f(x)) / h
Cette fonction prend elle-même une fonction en argument. Il faut que \(x\) et \(x+h\) appartiennent à son domaine. Pour \(f(x)=x^2\), \(x=2\) et \(h=0{,}1\), le résultat mathématique vaut
à comparer à \(f'(2)=4\). Un \(h\) excessivement petit peut amplifier les erreurs d'arrondi lors de la soustraction : « plus petit » n'est pas une garantie universelle.
Listes : une suite de cases, indexées à partir de zéro
L = [4, 7, 9]
print(L[0], L[-1], len(L)) # 4 9 3
L[1] = 8 # modification : [4, 8, 9]
L.append(12) # extension : [4, 8, 9, 12]
dernier = L.pop() # renvoie 12 et le supprime
del L[0] # suppression par indice : [8, 9]
carres = [k**2 for k in range(5)]
positifs = [x for x in [-2, 0, 3, 5] if x > 0]
for valeur in carres:
print(valeur)
for indice in range(len(carres)):
print(indice, carres[indice])
Pour une liste de longueur \(m\), les indices positifs autorisés sont \(0\) à \(m-1\). L[m] est en dehors de la liste. append ajoute une case à la fin ; la compréhension [k**2 for k in range(5)] construit \([0,1,4,9,16]\). La liste positifs vaut \([3,5]\) : le test placé après if filtre les éléments, sans modifier la liste parcourue. Remplacer \(>\) par \(\geqslant\) inclurait aussi 0.
Boucle while : prévoir pourquoi elle s'arrête
u = 100
n = 0
while u <= 200:
u = 1.05 * u
n = n + 1
print(n) # 15
Le test a lieu avant chaque passage. La boucle continue tant que \(u\leqslant200\) ; elle s'arrête au premier \(u>200\). Après \(n\) passages, \(u=100\times1{,}05^n\). Cette suite tend vers \(+\infty\), donc elle finit par franchir 200. On obtient \(n=15\) ; \(100\times1{,}05^{14}<200\) et \(100\times1{,}05^{15}>200\).
Petits outils réutilisables et tests pertinents
Les fonctions numériques suivantes utilisent un contrôle commun pour leurs nombres d'étapes. raise ValueError signale une entrée qui ne respecte pas le contrat ; ce n'est pas un résultat mathématique.
from math import isfinite
def entier_naturel(n, minimum=0):
if type(n) is not int or n < minimum:
raise ValueError("entier hors du domaine demandé")
def probabilite(p):
if not 0 <= p <= 1:
raise ValueError("p doit appartenir à [0, 1]")
Le programme peut vérifier un entier, un signe ou une borne. Il ne peut pas déduire d'un simple test que les tirages de ton modèle sont indépendants, ni qu'une fonction est continue sur tout un intervalle. Ces hypothèses restent à établir dans le raisonnement. Dans les programmes suivants, isfinite(x) vérifie que le nombre flottant n'est ni infini ni indéterminé ; all(liste) renvoie vrai si tous les tests de la liste sont vrais. Par exemple all([True, False]) vaut False. La compréhension [isfinite(x) for x in [a,b]] produit un test pour chaque borne. Tester un cas connu, un cas frontière et un contre-exemple ciblé est plus instructif que lancer seulement un gros calcul. Une série finie de tests ne prouve pas un énoncé « pour tout entier » ; un seul résultat contraire suffit toutefois à le réfuter.
Dichotomie : garder une solution entre deux bornes
Le dessin avant le programme
Pour \(f(x)=x^2-2\) sur \([1,2]\), les signes sont \(-\) puis \(+\). Au milieu \(1{,}5\), \(f(1{,}5)=0{,}25>0\) : on garde \([1,1{,}5]\). Le milieu suivant est \(1{,}25\) ; son image vaut \(-0{,}4375\), donc on garde \([1{,}25,1{,}5]\).
Un intervalle en sortie, puis un centre
Le contrat demande \(\varepsilon>0\), des bornes finies et les hypothèses précédentes. Les valeurs calculées de \(f\) doivent être finies. Le contrôle de signe évite de multiplier deux valeurs flottantes potentiellement très grandes ou très petites.
def dichotomie_intervalle(f, a, b, eps):
if not all([isfinite(x) for x in [a, b, eps]]):
raise ValueError("bornes et tolérance finies")
if not a < b or eps <= 0:
raise ValueError("a < b et eps > 0 requis")
fa, fb = f(a), f(b)
if not isfinite(fa) or not isfinite(fb):
raise ValueError("images non finies")
if fa == 0:
return [a, a]
if fb == 0:
return [b, b]
if (fa < 0) == (fb < 0):
raise ValueError("signes opposés requis")
while b - a > eps:
m = a / 2 + b / 2
if m == a or m == b:
raise ArithmeticError("précision flottante atteinte")
fm = f(m)
if not isfinite(fm):
raise ValueError("image non finie")
if fm == 0:
return [m, m]
if (fa < 0) == (fm < 0):
a, fa = m, fm
else:
b = m
return [a, b]
Chaque branche conserve des signes opposés : si le milieu a le même signe que la borne gauche, on déplace cette borne gauche. Sinon on déplace la droite. La valeur de fa doit suivre celle de a.
def dichotomie(f, a, b, eps):
bornes = dichotomie_intervalle(f, a, b, eps)
return bornes[0] / 2 + bornes[1] / 2
def carre_moins_deux(x):
return x**2 - 2
print(dichotomie_intervalle(carre_moins_deux, 1, 2, 0.01))
En arithmétique exacte, la largeur finale est au plus eps et l'erreur du centre au plus eps/2. En flottants, les signes évalués et les milieux subissent des arrondis : le programme signale une stagnation, mais ne constitue pas un calcul certifié par arithmétique d'intervalles. Aux précisions usuelles, contrôler aussi la cohérence du résultat avec le graphe et l'étude de \(f\).
Euler : avancer avec la pente actuelle
De la tangente à une suite de points
Pour
La valeur exacte en \(t=1\) est \(\e\approx2{,}71828\). En quatre pas de \(0{,}25\), Euler donne \(1{,}25^4=2{,}44140625\), ici plus proche.
Les segments relient les points calculés. Ils montrent la construction polygonale d'Euler ; seule la courbe verte représente la solution exacte de cet exemple.
Programmer et interpréter le pas
def euler(f, t0, y0, h, n):
entier_naturel(n)
if not all([isfinite(x) for x in [t0, y0, h]]) or h <= 0:
raise ValueError("données finies et h > 0 requis")
T, Y = [t0], [y0]
t, y = t0, y0
for k in range(n):
pente = f(t, y)
y = y + h * pente
t = t0 + (k + 1) * h
if not isfinite(t) or not isfinite(y):
raise ArithmeticError("calcul non fini")
T.append(t)
Y.append(y)
return [T, Y]
Les listes ont \(n+1\) valeurs car elles incluent le point initial. La pente utilise l'ancien couple \((t,y)\) ; on ne met pas à jour le temps avant de la calculer. Pour \(n=0\), on renvoie seulement les données initiales.
Intégrer avec des rectangles
Choisir la hauteur et conserver le signe
On suppose \(f\) continue sur \([a,b]\), \(a<b\), et \(n\geqslant1\) entier. Posons \(h=(b-a)/n\) et \(x_k=a+kh\). Les trois sommes suivantes choisissent la hauteur au bord gauche, au bord droit ou au milieu de chaque intervalle :
Les trois convergent vers \(\int_a^b f(x)\,\mathrm dx\) quand \(n\to+\infty\). Une hauteur négative fournit une contribution négative : l'intégrale est une aire algébrique, pas toujours une aire positive.
Ici \(f(x)=x^2\), \([a,b]=[0,1]\), \(n=4\). Le premier rectangle a une hauteur nulle. La somme gauche vaut
et la somme droite
La fonction étant croissante, elles encadrent l'intégrale \(1/3\).
Une fonction commune pour éviter trois copies presque identiques
def riemann(f, a, b, n, position):
entier_naturel(n, 1)
if not all([isfinite(x) for x in [a, b]]) or not a < b:
raise ValueError("bornes finies et a < b requis")
if position not in [0, 0.5, 1]:
raise ValueError("position : 0, 0.5 ou 1")
h = (b - a) / n
S = 0
for k in range(n):
x = a + (k + position) * h
valeur = f(x)
if not isfinite(valeur):
raise ValueError("image non finie")
S = S + valeur
return h * S
def riemann_gauche(f, a, b, n):
return riemann(f, a, b, n, 0)
def riemann_droite(f, a, b, n):
return riemann(f, a, b, n, 1)
def riemann_milieu(f, a, b, n):
return riemann(f, a, b, n, 0.5)
Le paramètre position déplace le point d'évaluation à l'intérieur de chaque intervalle. Les trois fonctions courtes expriment l'intention et réutilisent le même calcul. Cette organisation en petites fonctions est la programmation modulaire.
Simuler : prévoir ce qui change et ce qui reste fixe
Une épreuve, un échantillon, plusieurs échantillons
random() produit un nombre pseudo-aléatoire dans \([0,1[\). Dans le modèle continu idéal uniforme, la proportion de cet intervalle située sous \(p\) est \(p\). Le test random() < p permet ainsi de simuler une Bernoulli de paramètre \(p\). Les appels successifs servent à modéliser des essais indépendants ; répéter un résultat déjà tiré ne simule pas de nouveaux essais.
from random import random, randint, choice
def bernoulli(p):
probabilite(p)
if random() < p:
return 1
return 0
def binomiale(n, p):
entier_naturel(n)
probabilite(p)
S = 0
for k in range(n):
S = S + bernoulli(p)
return S
def frequence(n, p):
entier_naturel(n, 1)
return binomiale(n, p) / n
def echantillons(N, n, p):
entier_naturel(N, 1)
entier_naturel(n, 1)
probabilite(p)
return [frequence(n, p) for _ in range(N)]
binomiale(0,p) vaut 0 ; une fréquence sur zéro essai n'est pas définie. Pour \(p=0\), tous les résultats valent 0 ; pour \(p=1\), ils valent 1. Le caractère _ est ici un nom de boucle dont la valeur n'est pas utilisée. echantillons(100,20,0.3) renvoie 100 fréquences, calculées chacune sur 20 essais. Les nombres \(N\) et \(n\) n'ont pas le même rôle.
Voir une trajectoire, puis comparer des dispersions
def frequences_cumulees(n, p):
entier_naturel(n, 1)
probabilite(p)
S = 0
valeurs = []
for k in range(1, n + 1):
S = S + bernoulli(p)
valeurs.append(S / k)
return valeurs
La liste commence par la fréquence après un essai. Le graphique doit donc utiliser les abscisses de 1 à \(n\), et non de 0 à \(n-1\).
# Affichage facultatif : nécessite matplotlib.
import matplotlib.pyplot as plt
n, p = 200, 0.5
valeurs = frequences_cumulees(n, p)
plt.plot(range(1, n + 1), valeurs)
plt.axhline(p, color="black", linestyle="--")
plt.xlabel("Nombre d'essais")
plt.ylabel("Fréquence observée")
plt.show()
La fréquence peut s'éloigner de \(p\) à l'étape suivante. La loi des grands nombres décrit un risque d'écart pour une taille croissante, pas une obligation de rapprochement à chaque tirage.
La fiche 17 complète ce travail : simuler \(N\) échantillons de taille \(n\), comparer leur écart-type observé à \(\sqrt{p(1-p)/n}\), puis compter les fréquences à moins de un, deux et trois écarts-types théoriques de \(p\). Comparer plusieurs tailles et répéter avec un nouveau lot. Cela explore la variabilité ; un lot simulé ne démontre pas une borne de probabilité.
Suites, seuils et recherche sur une grille
Stocker les termes : le rang zéro compte aussi
def termes_suite(f, u0, n):
entier_naturel(n)
termes = [u0]
u = u0
for k in range(n):
u = f(u)
termes.append(u)
return termes
Le contrat demande que \(f\) soit définie sur tous les termes rencontrés. La liste contient \(u_0\) à \(u_n\), donc \(n+1\) termes. Pour obtenir les vingt premiers termes, on demande \(n=19\). Le rang d'une case coïncide ici avec celui de la suite : termes[k] vaut \(u_k\).
Limiter la recherche sans inventer une conclusion
def seuil_borne(f, u0, M, max_iter=10000):
entier_naturel(max_iter)
if not isfinite(u0) or not isfinite(M):
raise ValueError("valeurs finies requises")
u = u0
for n in range(max_iter + 1):
if u > M:
return n
if n < max_iter:
u = f(u)
if not isfinite(u):
raise ArithmeticError("terme non fini")
return None
Si un rang est renvoyé, tous les rangs précédents ont été testés et ont échoué : c'est le premier franchissement strict dans la plage explorée. None signifie « aucun franchissement trouvé jusqu'à max_iter », pas « aucun franchissement n'existe ». Si \(u_0>M\), le résultat est 0, même avec zéro mise à jour autorisée. Une preuve de limite peut établir à part qu'un seuil sera finalement franchi.
Un maximum calculé sur des points, pas automatiquement sur tout un intervalle
def maximum_balayage(f, a, b, n):
entier_naturel(n, 1)
if not all([isfinite(x) for x in [a, b]]) or not a < b:
raise ValueError("bornes finies et a < b requis")
x_max, y_max = a, f(a)
if not isfinite(y_max):
raise ValueError("image non finie")
for k in range(1, n + 1):
x = a + (b - a) * k / n
y = f(x)
if not isfinite(y):
raise ValueError("image non finie")
if y > y_max:
x_max, y_max = x, y
return [x_max, y_max]
Il y a \(n+1\) points, bornes incluses. On initialise le maximum à \(f(a)\), ce qui fonctionne aussi si toutes les valeurs sont négatives. Avec le test strict, la première abscisse rencontrée est conservée en cas d'égalité.
Triangle de Pascal : utiliser la ligne précédente
def pascal(n):
entier_naturel(n)
lignes = [[1]]
for k in range(1, n + 1):
precedente = lignes[-1]
ligne = [1]
for j in range(1, k):
ligne.append(precedente[j - 1] + precedente[j])
ligne.append(1)
lignes.append(ligne)
return lignes
La ligne 0 est \([1]\), les suivantes \([1,1]\), \([1,2,1]\), \([1,3,3,1]\). Le coefficient lignes[k][j] vaut \(\binom{k}{j}\). La formule de Pascal additionne deux cases de la ligne précédente ; une nouvelle liste est créée à chaque tour.
Choisir, expliquer, vérifier
Exercices
Exercice 1 ★☆☆ : Lire un algorithme
Que retourne la fonction suivante pour n = 5 ?
def mystere(n):
S = 0
for k in range(1, n + 1):
S = S + k**2
return S
Exercice 2 ★☆☆ : Compléter un algorithme
Pour un entier \(n\geqslant0\), compléter le programme pour qu'il calcule \(n!\) (factorielle de \(n\)) :
def factorielle(n):
F = ... # à compléter
for k in range(..., ...): # à compléter
F = ... # à compléter
return F
Exercice 3 ★☆☆ : Suite récurrente
On définit \(u_0=1\) et \(u_{n+1}=\frac{u_n+3}{2}\).
Écrire un programme qui affiche les \(20\) premiers termes.
Vers quelle valeur semble converger la suite ?
Écrire un programme qui détermine le plus petit \(n\) tel que \(|u_n-3|<10^{-6}\).
Exercice 4 ★★☆ : Dichotomie
Utiliser la dichotomie pour résoudre \(\e^x=3x\) sur \([1,2]\) à \(10^{-8}\) près.
Combien d'étapes suffisent pour une largeur finale au plus \(10^{-8}\) ?
Adapter pour trouver \(\sqrt[3]{7}\) (zéro de \(x^3-7\) sur \([1,2]\)).
Exercice 5 ★★☆ : Méthode d'Euler
Appliquer Euler à \(y'=y\), \(y(0)=1\) avec \(h=0{,}1\) et \(n=10\) (donc \(t\in[0,1]\)). Comparer \(y_{10}\) à \(\e\).
Même question avec \(h=0{,}01\) et \(n=100\). L'approximation est-elle meilleure ?
Approfondissement. Appliquer Euler à \(y'=-y+\sin(t)\), \(y(0)=0\) avec \(h=0{,}01\) sur \([0,10]\). Tracer la solution.
Exercice 6 ★★☆ : Sommes de Riemann
Calculer \(\int_0^1 x^3\,\mathrm{d}x\) par les sommes à gauche avec \(n=100\), \(1000\), \(10000\). Comparer à la valeur exacte \(\frac{1}{4}\).
Calculer \(\int_0^\pi\sin(x)\,\mathrm{d}x\) par la méthode des milieux. Comparer à \(2\).
Estimer \(\int_0^1\frac{1}{1+x^2}\,\mathrm{d}x\) et vérifier que c'est \(\approx\frac{\pi}{4}\).
Exercice 7 ★★☆ : Simulation de probabilités
Simuler \(10\,000\) lancers indépendants de deux dés équilibrés indépendants et estimer la probabilité d'obtenir une somme égale à \(7\).
Simuler le paradoxe des anniversaires : pour \(n\) personnes, estimer la probabilité d'une coïncidence dans le modèle de dates indépendantes et uniformes parmi 365 jours.
Simuler la marche aléatoire : un pion part de \(0\) et avance de \(+1\) ou \(-1\) (équiprobable), indépendamment à chaque pas. Tracer \(5\) trajectoires sur \(1000\) pas.
Exercice 8 ★★☆ : Lecture et compréhension
Que calcule la fonction suivante ? On suppose \(\varepsilon>0\) et une précision compatible avec les flottants ; le cours fournit une version qui détecte la stagnation.
import math
def f(x):
return math.log(x) - 2
def algo(eps):
a, b = 1, 100
while b - a > eps:
m = (a + b) / 2
if f(a) * f(m) <= 0:
b = m
else:
a = m
return (a + b) / 2
Quelle équation résout cet algorithme ?
Distinguer le zéro exact de l'équation et la valeur renvoyée par
algo(0.001). Donner l'intervalle final, son centre et une borne d'erreur.
Exercice 9 ★★☆ : Seuil et suite géométrique
Un modèle de capitalisation part de \(1000\)€ avec un taux annuel supposé constant de \(3\%\), sans versement ni retrait.
Écrire la suite \((u_n)\) du capital après \(n\) années.
Écrire un programme qui détermine le nombre d'années pour doubler le capital.
Vérifier en résolvant l'inégalité \(1{,}03^n>2\) et choisir le premier rang entier.
Exercice 10 ★★☆ : Exécuter à la main
Exécuter à la main l'algorithme suivant et donner la valeur de S en sortie :
S = 0
u = 1
for k in range(5):
S = S + u
u = u * 2
print(S)
Exercice 11 ★★☆ : Euler et équation différentielle
On considère l'équation \(y'=-0{,}5y+2\), \(y(0)=10\).
Déterminer la solution exacte.
Appliquer Euler avec \(h=0{,}5\) et faire les 4 premières étapes à la main.
Comparer avec les valeurs exactes en \(t=0{,}5\), \(1\), \(1{,}5\), \(2\).
Exercice 12 ★★☆ : Intervalle de confiance par simulation
On ne connaît pas \(p\) (probabilité de succès d'un événement). On effectue \(n=1000\) essais indépendants de même loi de Bernoulli de paramètre \(p\) et on observe \(f_n=0{,}62\).
Donner un intervalle de confiance théorique pour \(p\) au seuil \(95\%\) (Tchebychev).
En utilisant la marge \(\delta=\sqrt{5/n}\) obtenue par Tchebychev, simuler \(10\,000\) échantillons de taille \(1000\) avec \(p=0{,}6\). Estimer la proportion des fréquences à distance au plus \(\delta\) de \(p\). Expliquer pourquoi elle n'a pas à valoir exactement \(95\%\) et pourquoi la simulation ne prouve pas la garantie.
Exercice 13 ★★★ : Méthode de Monte-Carlo
Pour estimer \(\pi\) : on tire indépendamment et uniformément \(n\) points \((x,y)\) dans le carré \([0,1]^2\) et on compte ceux qui tombent dans le quart de disque \(x^2+y^2\leqslant 1\).
Expliquer pourquoi la fréquence des points dans le disque converge vers \(\frac{\pi}{4}\).
Écrire le programme. Estimer \(\pi\) pour \(n=10^4\) et \(n=10^6\).
Pour \(n=10^6\), calculer ou majorer l'écart-type de \(4\overline X_n\). Distinguer cette dispersion d'une erreur maximale, puis donner une marge suffisante à risque au plus \(5\%\) par Tchebychev.
Exercice 14 ★★★ : Approfondissement : Euler et solution exacte
On considère \(y'=\cos(t)-y\), \(y(0)=0\).
La solution exacte est \(y(t)=\frac{1}{2}(\sin t+\cos t-\e^{-t})\). Vérifier en dérivant.
Programmer Euler avec \(h=0{,}1\), \(h=0{,}01\), \(h=0{,}001\) sur \([0,10]\).
Tracer sur le même graphique les 3 approximations et la solution exacte.
Mesurer l'erreur maximale aux points calculés pour chaque \(h\). Comparer les erreurs divisées par \(h\) ; distinguer une observation numérique d'une preuve de proportionnalité.
Approfondissement : la méthode de Newton
Soit \(f\) dérivable sur un intervalle, et \(\alpha\) un zéro recherché. Dans les questions qui utilisent Taylor, on suppose de plus \(f\) de classe \(C^2\) près de \(\alpha\) et \(f'(\alpha)\ne0\).
Partie A : La construction géométrique
Écrire la tangente au point d'abscisse \(x_n\).
Si \(f'(x_n)\ne0\), déterminer l'abscisse \(x_{n+1}\) où elle coupe l'axe horizontal. Retrouver \(x_{n+1}=x_n-f(x_n)/f'(x_n)\).
Pour \(f(x)=x^2-2\) et \(x_0=1\), placer la première tangente et sa rencontre avec l'axe. Cette rencontre est-elle déjà le zéro de \(f\) ?
Partie B : Programmer et définir l'arrêt
Écrire
newton(f, df, x0, eps, max_iter). On exige \(\varepsilon>0\) et on accepte un résultat seulement si \(|f(x)|<\varepsilon\). Signaler un échec si la dérivée est nulle hors d'un zéro ou si le nombre maximal de mises à jour est atteint.Appliquer à \(x^2-2\) avec \(x_0=1\) et \(\varepsilon=10^{-15}\). Comparer le résidu \(|f(x)|\) à l'erreur \(|x-\sqrt2|\) : ce sont deux nombres différents.
Combien de divisions par deux suffisent pour qu'un intervalle initial \([1,2]\) ait une largeur au plus \(10^{-15}\) ? Comparer des nombres d'étapes permet-il, seul, de comparer les temps de calcul ?
Partie C : Comprendre la convergence locale
Sous les hypothèses \(C^2\) et zéro simple, utiliser Taylor entre \(x_n\) et \(\alpha\) pour relier \(e_{n+1}=x_{n+1}-\alpha\) à \(e_n^2\).
Expliquer ce que signifie une borne \(|e_{n+1}|\leqslant C|e_n|^2\) près du zéro. Pourquoi ne garantit-elle pas un doublement exact des décimales à toutes les étapes ni en précision flottante limitée ?
Dans le cas \(x^2-2\), calculer \(x_1\) à \(x_4\). Justifier l'identité exacte \(e_{n+1}=e_n^2/(2x_n)\) pour \(x_n>0\).
Partie D : Comprendre les échecs et conserver un intervalle
Examiner \(f(x)=x^3-1\) avec \(x_0=0\). Comparer avec \(f(x)=x^2\) et \(x_0=0\) : la dérivée est nulle dans les deux cas, mais les situations sont-elles identiques ?
Calculer deux étapes pour \(f(x)=x^3-2x+2\) avec \(x_0=0\). Que constate-t-on ?
Proposer une méthode hybride qui conserve des signes opposés : accepter une proposition de Newton seulement si elle appartient à la moitié centrale de l'intervalle courant ; sinon choisir le milieu. Expliquer pourquoi la largeur se réduit alors d'un facteur au plus \(3/4\) à chaque étape sans zéro exact.
Corrigés détaillés
Les fonctions du cours sont réutilisées ci-dessous : exécuter leurs définitions et les imports avant les appels. Les affichages de simulations changent d'une exécution à l'autre. Les variantes proposées dans les pauses servent à refaire le raisonnement sans recopier ce corrigé.
Exercice 1
| \(k\) | \(k^2\) | \(S\) avant | \(S\) après |
|---|---|---|---|
| 1 | 1 | 0 | 1 |
| 2 | 4 | 1 | 5 |
| 3 | 9 | 5 | 14 |
| 4 | 16 | 14 | 30 |
| 5 | 25 | 30 | 55 |
Le résultat est \(55\). Pour un entier \(n\geqslant0\), l'invariant du cours justifie que le programme donne \(\sum_{k=1}^n k^2\). La formule connue \(n(n+1)(2n+1)/6\) fournit un contrôle indépendant ; elle n'est pas nécessaire à l'exécution de la boucle.
Exercice 2
def factorielle(n):
entier_naturel(n)
F = 1
for k in range(1, n + 1):
F = F * k
return F
On initialise à 1 pour un produit. Après les facteurs 1 à \(k\), \(F=k!\). Pour \(n=0\), la boucle est vide : elle renvoie 1, conformément à \(0!=1\). Initialiser à 0 annulerait tous les produits.
Exercice 3
a) Afficher \(u_0\) avant la mise à jour permet de voir exactement les vingt termes \(u_0\) à \(u_{19}\) :
u = 1
for n in range(20):
print(n, u)
u = (u + 3) / 2
b) Les premiers termes \(1,2,2{,}5,2{,}75,\ldots\) suggèrent la limite 3. Une équation de point fixe fournit un candidat, mais ne prouve pas la convergence. Posons \(v_n=u_n-3\). Alors
Avec \(v_0=-2\), la suite géométrique donne \(v_n=-2(1/2)^n\), donc
c)
u = 1
n = 0
while abs(u - 3) >= 1e-6:
u = (u + 3) / 2
n = n + 1
print(n) # 21
La terminaison suit de \(|u_n-3|\to0\). Le seuil strict demandé donne
Le premier entier est 21 ; contrôler les rangs 20 et 21 permet aussi de vérifier le test de boucle.
Exercice 4
a) La fonction \(f(x)=\e^x-3x\) est continue sur \([1,2]\). Ses valeurs aux bornes sont de signes opposés : \(f(1)=\e-3<0\) et \(f(2)=\e^2-6>0\). Elle décroît jusqu'à \(\ln3\), puis croît strictement ; son minimum est négatif et elle reste négative sur \([1,\ln3]\). Il y a donc exactement un zéro dans \([1,2]\).
from math import exp
def equation_ex4(x):
return exp(x) - 3*x
print(dichotomie(equation_ex4, 1, 2, 1e-8))
print(dichotomie(lambda x: x**3 - 7, 1, 2, 1e-8))
lambda x: x**3 - 7 est une écriture courte d'une fonction renvoyant \(x^3-7\) ; on peut la remplacer par une définition def. Le premier résultat vaut environ \(1{,}51213455\). La largeur visée est \(10^{-8}\), donc la borne idéale d'erreur du centre est \(5\times10^{-9}\).
b) Sans rencontre d'un zéro exact, on cherche \(2^{-k}\leqslant10^{-8}\) :
Il suffit de 27 étapes pour la largeur demandée. C'est un contrôle de largeur, pas un test sur la seule taille de \(f(x)\).
c) La fonction \(x^3-7\) est continue et strictement croissante sur \([1,2]\), avec valeurs \(-6\) et 1. Son unique zéro est \(\sqrt[3]7\approx1{,}91293118\).
Exercice 5
a) La solution exacte de \(y'=y\), \(y(0)=1\) est \(\e^t\). Euler donne
Ainsi \(y_k=(1+h)^k\). Avec \(h=0{,}1\) et \(k=10\),
L'erreur absolue vaut environ \(0{,}12453937\) ; l'erreur relative est \(|y_{10}-\e|/\e\approx4{,}582\%\).
b) Avec \(h=0{,}01\) et \(k=100\), le même calcul donne \(1{,}01^{100}\approx2{,}70481383\), soit une erreur relative d'environ \(0{,}495\%\). On compare au même instant final \(t=1\) ; cette précision est ici meilleure.
c) Extension à une équation dépendant du temps :
from math import sin
import matplotlib.pyplot as plt
T, Y = euler(lambda t, y: -y + sin(t), 0, 0, 0.01, 1000)
plt.plot(T, Y)
plt.xlabel("t")
plt.ylabel("Approximation d'Euler")
plt.show()
Exercice 6
a) Une primitive de \(x^3\) est \(x^4/4\) ; l'intégrale vaut donc \(1/4\). La somme gauche s'écrit
La dernière égalité utilise la formule \(\sum_{k=1}^{m}k^3=[m(m+1)/2]^2\) ; le programme ne dépend pas de cette formule.
| \(n\) | \(L_n\) exact | \(1/4-L_n\) exact |
|---|---|---|
| 100 | \(0{,}245025\) | \(0{,}004975\) |
| 1000 | \(0{,}24950025\) | \(0{,}00049975\) |
| 10000 | \(0{,}2499500025\) | \(0{,}0000499975\) |
L'erreur vaut \(1/(2n)-1/(4n^2)\) ; son terme dominant est \(1/(2n)\).
b) Une primitive de \(\sin x\) est \(-\cos x\), d'où l'intégrale 2. Avec \(n=10000\), la somme des milieux est environ \(2{,}00000000822467\), soit un écart d'environ \(8{,}225\times10^{-9}\). Ici \(|f''|\leqslant1\) : la borne des milieux donnée dans l'approfondissement justifie déjà un écart au plus \(\pi^3/(24n^2)\).
c) Le calcul numérique suivant donne environ \(0{,}78539816\) :
from math import sin, pi
print(riemann_milieu(sin, 0, pi, 10000))
print(riemann_milieu(lambda x: 1 / (1 + x*x), 0, 1, 10000))
La valeur exacte \(\pi/4\) peut être établie avec la primitive \(\arctan x\), hors des primitives usuelles de ce socle. La concordance numérique est une vérification, pas une preuve de cette identité.
Exercice 7
a) Dans le modèle de deux dés équilibrés indépendants, les 36 couples sont équiprobables ; six donnent la somme 7. La probabilité est \(6/36=1/6\).
def somme_sept(N):
entier_naturel(N, 1)
compteur = 0
for k in range(N):
d1 = randint(1, 6)
d2 = randint(1, 6)
if d1 + d2 == 7:
compteur = compteur + 1
return compteur / N
b) On adopte un modèle simplifié : dates indépendantes et uniformes parmi 365 jours, sans année bissextile. Il ne décrit pas exactement les fréquences calendaires réelles. Une liste mémorise les dates déjà rencontrées. Le mot break quitte la boucle courante dès qu'une collision est trouvée ; les autres personnes ne changeraient plus l'événement recherché.
def anniversaire_simulation(n, N=10000):
entier_naturel(n)
entier_naturel(N, 1)
if n > 365:
return 1.0
compteur = 0
for k in range(N):
dates = []
collision = False
for j in range(n):
d = randint(1, 365)
if d in dates:
collision = True
break
dates.append(d)
if collision:
compteur = compteur + 1
return compteur / N
Pour 23 personnes, la probabilité exacte du modèle vaut
La simulation fluctue autour de cette valeur. Pour zéro ou une personne, il n'y a jamais de collision ; au-delà de 365 personnes, il y en a forcément une dans ce modèle.
c) Chaque appel simule une marche à pas indépendants, de valeurs \(-1\) et 1 équiprobables. La liste inclut la position initiale :
def marche(n):
entier_naturel(n)
positions = [0]
x = 0
for k in range(n):
x = x + choice([-1, 1])
positions.append(x)
return positions
import matplotlib.pyplot as plt
for repetition in range(5):
plt.plot(range(1001), marche(1000), linewidth=0.7)
plt.xlabel("Nombre de pas")
plt.ylabel("Position")
plt.show()
Un contrôle simple : après \(k\) pas, la position est entre \(-k\) et \(k\) et a la même parité que \(k\).
Exercice 8
a) Sur \([1,100]\), \(\ln x-2\) est continue et strictement croissante, de signes opposés aux bornes. Le zéro exact est \(\e^2\).
b) Avec le programme proposé et eps = 0.001, on effectue 17 divisions par deux. L'intervalle final est
Le centre renvoyé est le nombre dyadique
C'est la valeur exacte du centre obtenu dans cette exécution, et une approximation de \(\e^2\approx7{,}38905609893\). Sa distance au zéro est inférieure à la demi-largeur \(99/2^{18}\approx0{,}000377655\), elle-même inférieure à \(0{,}0005\). Confondre « solution exacte de l'équation » et « valeur retournée » ferait perdre l'information principale de l'algorithme.
Exercice 9
a) Dans le modèle théorique à taux fixe de 3% chaque année, \(u_0=1000\), \(u_{n+1}=1{,}03u_n\), donc \(u_n=1000\times1{,}03^n\).
b) Pour dépasser strictement 2000 :
u = 1000
n = 0
while u <= 2000:
u = 1.03 * u
n = n + 1
print(n) # 24
c) La croissance du logarithme et \(\ln1{,}03>0\) donnent
Le premier entier est 24. La suite tend vers \(+\infty\), ce qui justifie la terminaison. Cette situation sert de modèle de suite géométrique, à taux supposé constant.
Exercice 10
| \(k\) | \(S\) avant | \(u\) avant | \(S\) après | \(u\) après |
|---|---|---|---|---|
| 0 | 0 | 1 | 1 | 2 |
| 1 | 1 | 2 | 3 | 4 |
| 2 | 3 | 4 | 7 | 8 |
| 3 | 7 | 8 | 15 | 16 |
| 4 | 15 | 16 | 31 | 32 |
On additionne \(u\) avant de le doubler. La somme affichée est \(1+2+4+8+16=31\). Le dernier \(u=32\) a été calculé mais n'a pas été additionné. Pour \(n\) passages, la somme est \(2^n-1\), y compris \(n=0\).
Exercice 11
a) Les solutions de \(y'=-0{,}5y+2\) sont \(y(t)=C\e^{-0{,}5t}+4\). La condition initiale donne \(C+4=10\), donc \(C=6\).
b) Le pas \(h=0{,}5\) conduit à
En conservant les valeurs exactes à chaque étape :
c) Comparaison avec \(y(t)=4+6\e^{-0{,}5t}\) ; les colonnes « exacte » et « erreur relative » sont arrondies :
| \(t\) | Euler | Solution exacte | Erreur relative |
|---|---|---|---|
| \(0{,}5\) | \(8{,}5\) | \(8{,}672805\) | \(1{,}99\%\) |
| 1 | \(7{,}375\) | \(7{,}639184\) | \(3{,}46\%\) |
| \(1{,}5\) | \(6{,}53125\) | \(6{,}834199\) | \(4{,}43\%\) |
| 2 | \(5{,}8984375\) | \(6{,}207277\) | \(4{,}98\%\) |
L'erreur relative est \(|y_k-y(t_k)|/|y(t_k)|\). On n'arrondit pas les valeurs intermédiaires avant de poursuivre la récurrence.
Exercice 12
a) Pour \(n\) essais indépendants de même loi de Bernoulli de paramètre \(p\), la fréquence \(F_n\) a une variance \(p(1-p)/n\leqslant1/(4n)\). Pour \(\delta>0\), Tchebychev donne
Pour un risque au plus \(0{,}05\), on choisit
Avec \(n=1000\), la demi-largeur est \(\sqrt{5/1000}\approx0{,}07071068\). L'intervalle observé est \([0{,}62-\delta;0{,}62+\delta]\), contenu dans l'arrondi extérieur \([0{,}549;0{,}691]\). Avant l'observation, la procédure couvre le paramètre fixe \(p\) avec une probabilité d'au moins 95%. Après observation, cette phrase n'attribue pas à \(p\) une loi aléatoire dans l'intervalle obtenu.
b) On simule une fréquence de couverture :
from math import sqrt
def couverture(p, n, N):
entier_naturel(n, 1)
entier_naturel(N, 1)
probabilite(p)
marge = sqrt(5 / n)
compteur = 0
for k in range(N):
fn = frequence(n, p)
if abs(fn - p) <= marge:
compteur = compteur + 1
return compteur / N
# Expérience possible, plus longue que les petits tests du cours :
# print(couverture(0.6, 1000, 10000))
La couverture théorique peut être bien supérieure à 95% car Tchebychev fournit une borne prudente. La fréquence simulée fluctue aussi : elle n'a pas à valoir exactement \(0{,}95\), ni à être toujours au-dessus de \(0{,}95\) dans chaque lot. Une simulation ne prouve pas l'inégalité. Réduire la demi-largeur à \(1/\sqrt{20n}\) ferait perdre la garantie précédente : la borne obtenue serait même supérieure à 1 et donc sans information.
Exercice 13
a) Dans le modèle de points uniformes et indépendants du carré unité, l'indicatrice \(X_i\) du quart de disque suit une Bernoulli de paramètre \(q=\pi/4\). La loi des grands nombres donne la convergence en probabilité de leur moyenne vers \(q\). On estime alors \(\pi\) par \(4\overline X_n\).
def monte_carlo_pi(n):
entier_naturel(n, 1)
compteur = 0
for k in range(n):
x = random()
y = random()
if x*x + y*y <= 1:
compteur = compteur + 1
return 4 * compteur / n
b) On peut comparer les résultats de monte_carlo_pi(10000) puis monte_carlo_pi(1000000) à \(\pi\). Aucun nombre fixe de décimales exactes n'est promis pour une réalisation.
c) L'écart-type de l'estimateur est
Pour \(n=10^6\), il vaut environ \(0{,}001642\), avec borne \(0{,}002\). Un écart-type mesure une dispersion, pas une erreur maximale. Pour un risque d'écart au plus 5%, Tchebychev et la majoration de variance donnent la marge suffisante \(\sqrt{80/n}\approx0{,}008944\). La précision dépend donc aussi du risque choisi. Multiplier \(n\) par 100 divise l'écart-type par 10.
Exercice 14 : Approfondissement
a) Pour \(y(t)=\frac12(\sin t+\cos t-\e^{-t})\), on a
De plus,
Les deux conditions sont vérifiées.
b)–d) Le programme compare l'erreur aux points calculés. Les listes restent la seule collection utilisée ; le tracé facultatif nécessite Matplotlib.
from math import sin, cos, exp
import matplotlib.pyplot as plt
def exacte_ex14(t):
return (sin(t) + cos(t) - exp(-t)) / 2
for h in [0.1, 0.01, 0.001]:
n = round(10 / h)
T, Y = euler(lambda t, y: cos(t) - y, 0, 0, h, n)
erreurs = [abs(Y[k] - exacte_ex14(T[k]))
for k in range(len(T))]
print(h, max(erreurs))
plt.plot(T, Y, label=f"Euler h={h}")
temps = [10*k/1000 for k in range(1001)]
plt.plot(temps, [exacte_ex14(t) for t in temps], "k--",
label="Solution exacte")
plt.xlabel("t")
plt.legend()
plt.show()
| \(h\) | Maximum observé aux nœuds | Maximum divisé par \(h\) |
|---|---|---|
| \(0{,}1\) | \(\approx0{,}034174919\) | \(\approx0{,}341749\) |
| \(0{,}01\) | \(\approx0{,}003340880\) | \(\approx0{,}334088\) |
| \(0{,}001\) | \(\approx0{,}000333320\) | \(\approx0{,}333320\) |
Les rapports se rapprochent ici d'une constante ; les erreurs ne sont pas exactement proportionnelles à \(h\). Cela illustre un comportement d'ordre 1 dans ce problème régulier, sans démontrer à partir de trois mesures le théorème général ni le maximum sur tous les temps réels.
Corrigé du problème : Newton
1–3. La tangente a pour équation \(y=f(x_n)+f'(x_n)(x-x_n)\). Si \(f'(x_n)\ne0\), son intersection avec \(y=0\) vérifie
Pour \(x^2-2\) en \(x_0=1\), la tangente est
et coupe l'axe en \(1{,}5\). Mais \(1{,}5^2-2=0{,}25\), donc cette intersection n'est pas déjà le zéro de la courbe.
4. Le contrat porte sur un résidu strictement inférieur à eps. La fonction renvoie deux valeurs dans une liste : le résultat \(x\) et le nombre de mises à jour. Elle les renvoie uniquement lorsque ce critère est satisfait, sans garantir la convergence depuis tout point initial.
def newton(f, df, x0, eps, max_iter=100):
entier_naturel(max_iter)
if not isfinite(x0) or not isfinite(eps) or eps <= 0:
raise ValueError("données finies et eps > 0 requis")
x = x0
for i in range(max_iter + 1):
fx = f(x)
if not isfinite(fx):
raise ArithmeticError("image non finie")
if abs(fx) < eps:
return [x, i]
if i == max_iter:
raise RuntimeError("critère non atteint")
dfx = df(x)
if not isfinite(dfx) or dfx == 0:
raise ArithmeticError("dérivée inutilisable")
suivant = x - fx / dfx
if not isfinite(suivant) or suivant == x:
raise ArithmeticError("calcul bloqué en flottants")
x = suivant
On teste le résidu avant la dérivée : un zéro déjà trouvé est accepté, même si sa dérivée est nulle. max_iter = 0 autorise le contrôle du point initial mais aucune mise à jour.
5–6. Avec les flottants usuels, l'appel suivant effectue cinq mises à jour :
resultat, nb = newton(lambda x: x*x - 2,
lambda x: 2*x, 1, 1e-15)
print(resultat, nb)
Le résultat est environ \(1{,}4142135623730951\) et son résidu calculé environ \(4{,}44\times10^{-16}\). Pour ce problème particulier,
ce qui relie résidu et erreur. En général, un résidu petit ne suffit pas à borner l'erreur sans information supplémentaire sur \(f\) près de son zéro. En dichotomie, 50 divisions suffisent pour une largeur \(2^{-50}\leqslant10^{-15}\) ; la demi-largeur est encore deux fois plus petite. Les critères d'arrêt comparés sont différents et une étape de Newton calcule aussi une dérivée. On ne peut pas conclure à un temps d'exécution dix fois plus court sur ce seul comptage.
7–8. Sous les hypothèses \(C^2\) et zéro simple, Taylor entre \(x_n\) et \(\alpha\) donne un point \(\xi_n\) entre les deux tel que
Comme \(e_n=x_n-\alpha\), on réorganise sans supprimer les termes du dénominateur :
Près d'un zéro simple, \(|f'|\) reste minorée par un nombre strictement positif et \(|f''|\) est majorée : on obtient \(|e_{n+1}|\leqslant C|e_n|^2\). En choisissant le point initial assez près, cette borne garde les itérés dans le voisinage et entraîne leur convergence. Si \(x_n\to\alpha\), le coefficient tend vers \(f''(\alpha)/(2f'(\alpha))\) ; il peut être nul. La rapidité est locale, et les arrondis finissent par limiter les chiffres disponibles. Un doublement exact des décimales à chaque étape n'est pas une règle générale.
9. Calculs en arithmétique exacte pour Héron, puis approximations :
| \(n\) | \(x_n\) exact | \(x_n\) approché | \(|x_n-\sqrt2|\) approché |
|---|---|---|---|
| 1 | \(3/2\) | \(1{,}5\) | \(0{,}0857864\) |
| 2 | \(17/12\) | \(1{,}416666666667\) | \(0{,}00245310\) |
| 3 | \(577/408\) | \(1{,}414215686275\) | \(2{,}12390\times10^{-6}\) |
| 4 | \(665857/470832\) | \(1{,}414213562375\) | \(1{,}59486\times10^{-12}\) |
Les chiffres affichés sont arrondis. L'erreur après quatre mises à jour est de l'ordre de \(10^{-12}\), et non déjà celle de la cinquième mise à jour.
10–11. Pour \(x^3-1\) en 0, \(f(0)=-1\) et \(f'(0)=0\) : la tangente horizontale ne rencontre pas l'axe, donc aucune étape de Newton n'est définie. Pour \(x^2\) en 0, on a déjà un zéro ; il faut s'arrêter avant de diviser. Pour \(x^3-2x+2\), le cycle \(0\mapsto1\mapsto0\) a été détaillé dans la pause. La présence d'un zéro réel ne garantit pas la convergence depuis tout point initial.
12. Une hybridation doit conserver l'encadrement tout au long du calcul. Une seule phase de dichotomie suivie de Newton sans contrôle ne donnerait pas cette garantie. Voici une version guidée : elle propose Newton depuis le milieu, mais n'accepte le candidat que dans la moitié centrale. Les mêmes hypothèses de continuité, de signes et de calculs finis s'appliquent.
def newton_hybride(f, df, a, b, eps, max_iter=200):
entier_naturel(max_iter)
if not isfinite(eps) or eps <= 0:
raise ValueError("eps fini strictement positif")
a, b = dichotomie_intervalle(f, a, b, b - a)
fa = f(a)
for i in range(max_iter + 1):
if b - a <= eps:
return a / 2 + b / 2
if i == max_iter:
raise RuntimeError("largeur non atteinte")
m = a / 2 + b / 2
if m == a or m == b:
raise ArithmeticError("précision flottante atteinte")
fm = f(m)
if not isfinite(fm):
raise ArithmeticError("image non finie")
if fm == 0:
return m
d = df(m)
x = m
if isfinite(d) and d != 0:
candidat = m - fm / d
quart = (b - a) / 4
if a + quart <= candidat <= b - quart:
x = candidat
fx = f(x)
if not isfinite(fx):
raise ArithmeticError("image non finie")
if fx == 0:
return x
if (fa < 0) == (fx < 0):
a, fa = x, fx
else:
b = x
Fiche mémoire
Maîtrise du chapitre
Validation contrôlée
Réponds aux QCM, sélectionne les bonnes propositions ou remets les étapes dans l'ordre. Le site vérifie chaque réponse avant d'ouvrir la balise suivante.