Bonjour
je vous propose l'exercice suivant :
Ecrire un algorithme dans le language de votre choix permetant de determiner le premier carré parfait inferieur ou égal à un entier n choisit dans N .
On a droit à quelles fonctions standard ?
Si les fonctions racine () et int() sont autorisées, c'est trop facile :
def f(x) :
a=int(sqrt(x))
return a*a
Si on interdit les 2 fonctions partie-entières et racines carrée, ou une de ces 2 fonctions, le challenge devient beaucoup plus intéressant.
- Exercice 1 : on interdit la fonction racine carrée.
On a droit uniquement aux 4 opérations courantes, et à la fonction partie entière.
Le Héron, je m'attendais à le voir apparaître.
Mais ce Newton-Raphson, je ne connais pas du tout.
Oui, ce n'est pas le challenge du siècle, mais c'est un peu plus difficile que la question initiale.
Le problème pour Héron et Newton-Raphson, c'est le coté itératif à faire un certain nombre de fois. Du coup, utilisation de for ou while mais alors le problème initial est trivial.
Newton-Raphson est un algorithme simple pour trouver un zéro d'une fonction de R->R.
Tu prends un point initial x(0)
Et par récurrence tu définis x(n+1) = x(n) - f(x(n))/f'(x(n))
Si tu choisis correctement x(0) ça converge quadratiquement vers un zéro de f.
Ici pour f on prendrait f(x) = x^2-n et comme valeur initiale x(0) = n.
Comme je le disais ça converge très vite, donc avec 100 itérations (ce qui prend moins d'un quart de seconde) on sera très proche de sqrt(n).
Vu qu'on veut la partie entière c'est de toute façon pas très grave si on pas immensément proche. A +0.5 près à suffit.
Et la version Newton-Raphson avec juste des entiers (division entière) marche très bien pour la racine carrée.
Même plus besoin de passer par des float (nombres à virgules)
Avec des divisions entières on a la même convergence qu'avec des floats.
Pour les SIMD, la division entière est la division par défaut pour deux entiers la plupart du temps.
A noter que python a déjà la méthode toute faite pour nous:
Je suis étonné que tu aies besoin de 77 itérations, mais tu pars de n ce qui n'est pas une bonne approximation de la racine du tout.
En utilisant n >> (n.bit_length()>>1), j'obtiens la réponse en seulement 5 itérations pour le m que tu as utilisé.
def isqrt(n: int):
x = n >> (n.bit_length() >> 1)
while not (x * x <= n < (x + 1) * (x + 1)):
x = (x + n // x) >> 1
return x
Vous devez être membre accéder à ce service...
Pas encore inscrit ?
1 compte par personne, multi-compte interdit !
Ou identifiez-vous :