web-dev-qa-db-fra.com

Écrire votre propre fonction racine carrée

Comment écrivez-vous votre propre fonction pour trouver la racine carrée la plus précise d'un entier?

Après l'avoir googlé, j'ai trouvé this (archivé de son lien d'origine ), mais d'abord, je ne l'ai pas tout à fait compris, et ensuite, il est aussi approximatif.

Supposons que la racine carrée est l’entier le plus proche (de la racine réelle) ou un flottant.

67
Pale Blue Dot

Le calcul de l’étage suivant (sqrt (N)) pour N> 0:

x = 2^ceil(numbits(N)/2)
loop:
    y = floor((x + floor(N/x))/2)
    if y >= x
        return x
    x = y

Ceci est une version de la méthode de Newton donnée dans Crandall & Pomerance, "Les nombres premiers: une perspective informatique". La raison pour laquelle vous devriez utiliser cette version est que les personnes qui savent ce qu’elles font ont prouvé qu’elle converge exactement vers le sol de la racine carrée. C’est simple, donc la probabilité de faire une erreur d’implémentation est faible. C'est aussi rapide (bien qu'il soit possible de construire un algorithme encore plus rapide - mais le faire correctement est beaucoup plus complexe). Une recherche binaire correctement implémentée peut être plus rapide pour un très petit N, mais vous pouvez également utiliser une table de correspondance.

Pour arrondir au la plus proche entier, calculez simplement t = floor (sqrt (4N)) en utilisant l'algorithme ci-dessus. Si le bit le moins significatif de t est défini, choisissez x = (t + 1)/2; sinon choisissez t/2. Notez que cela se termine sur une cravate; vous pouvez aussi arrondir vers le bas (ou arrondir au pair) en vérifiant si le reste est différent de zéro (c’est-à-dire si t ^ 2 == 4N).

Notez que vous n'avez pas besoin d'utiliser l'arithmétique à virgule flottante. En fait, vous ne devriez pas. Cet algorithme doit être entièrement implémenté en utilisant des entiers (en particulier, les fonctions floor () indiquent simplement que la division entière doit être utilisée).

76
Fredrik Johansson

En fonction de vos besoins, une stratégie simple de division et de conquête peut être utilisée. Il ne convergera pas aussi bien que fast que d’autres méthodes, mais il peut être beaucoup plus facile à comprendre pour un novice. De plus, comme il s’agit d’un algorithme O (log n) (divisant par deux l’espace de recherche à chaque itération), le cas le plus défavorable pour un float 32 bits sera de 32 itérations.

Disons que vous voulez la racine carrée de 62.104. Vous choisissez une valeur à mi-chemin entre 0 et cela, et la place. Si le carré est supérieur à votre nombre, vous devez vous concentrer sur des nombres inférieurs au point médian. Si c'est trop bas, concentrez-vous sur ceux qui sont plus élevés.

En mathématiques réelles, vous pouvez diviser l’espace de recherche en deux pour toujours (s’il n’a pas de racine carrée rationnelle). En réalité, les ordinateurs finiront par manquer de précision et vous aurez votre approximation. Le programme C suivant illustre ce point:

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[]) {
    float val, low, high, mid, oldmid, midsqr;
    int step = 0;

    // Get argument, force to non-negative.

    if (argc < 2) {
        printf ("Usage: sqrt <number>\n");
        return 1;
    }
    val = fabs (atof (argv[1]));

    // Set initial bounds and print heading.

    low = 0;
    high = mid = val;
    oldmid = -1;

    printf ("%4s  %10s  %10s  %10s  %10s  %10s    %s\n",
        "Step", "Number", "Low", "High", "Mid", "Square", "Result");

    // Keep going until accurate enough.

    while (fabs(oldmid - mid) >= 0.00001) {
        oldmid = mid;

        // Get midpoint and see if we need lower or higher.

        mid = (high + low) / 2;
        midsqr = mid * mid;
        printf ("%4d  %10.4f  %10.4f  %10.4f  %10.4f  %10.4f  ",
            ++step, val, low, high, mid, midsqr);
        if (mid * mid > val) {
            high = mid;
            printf ("- too high\n");
        } else {
            low = mid;
            printf ("- too low\n");
        }
    }

    // Desired accuracy reached, print it.

    printf ("sqrt(%.4f) = %.4f\n", val, mid);
    return 0;
}

Voici quelques pistes pour que vous puissiez avoir une idée de son fonctionnement. Pour 77:

pax> sqrt 77
Step      Number         Low        High         Mid      Square    Result
   1     77.0000      0.0000     77.0000     38.5000   1482.2500  - too high
   2     77.0000      0.0000     38.5000     19.2500    370.5625  - too high
   3     77.0000      0.0000     19.2500      9.6250     92.6406  - too high
   4     77.0000      0.0000      9.6250      4.8125     23.1602  - too low
   5     77.0000      4.8125      9.6250      7.2188     52.1104  - too low
   6     77.0000      7.2188      9.6250      8.4219     70.9280  - too low
   7     77.0000      8.4219      9.6250      9.0234     81.4224  - too high
   8     77.0000      8.4219      9.0234      8.7227     76.0847  - too low
   9     77.0000      8.7227      9.0234      8.8730     78.7310  - too high
  10     77.0000      8.7227      8.8730      8.7979     77.4022  - too high
  11     77.0000      8.7227      8.7979      8.7603     76.7421  - too low
  12     77.0000      8.7603      8.7979      8.7791     77.0718  - too high
  13     77.0000      8.7603      8.7791      8.7697     76.9068  - too low
  14     77.0000      8.7697      8.7791      8.7744     76.9893  - too low
  15     77.0000      8.7744      8.7791      8.7767     77.0305  - too high
  16     77.0000      8.7744      8.7767      8.7755     77.0099  - too high
  17     77.0000      8.7744      8.7755      8.7749     76.9996  - too low
  18     77.0000      8.7749      8.7755      8.7752     77.0047  - too high
  19     77.0000      8.7749      8.7752      8.7751     77.0022  - too high
  20     77.0000      8.7749      8.7751      8.7750     77.0009  - too high
  21     77.0000      8.7749      8.7750      8.7750     77.0002  - too high
  22     77.0000      8.7749      8.7750      8.7750     76.9999  - too low
  23     77.0000      8.7750      8.7750      8.7750     77.0000  - too low
sqrt(77.0000) = 8.7750

Pour 62.104:

pax> sqrt 62.104
Step      Number         Low        High         Mid      Square    Result
   1     62.1040      0.0000     62.1040     31.0520    964.2267  - too high
   2     62.1040      0.0000     31.0520     15.5260    241.0567  - too high
   3     62.1040      0.0000     15.5260      7.7630     60.2642  - too low
   4     62.1040      7.7630     15.5260     11.6445    135.5944  - too high
   5     62.1040      7.7630     11.6445      9.7037     94.1628  - too high
   6     62.1040      7.7630      9.7037      8.7334     76.2718  - too high
   7     62.1040      7.7630      8.7334      8.2482     68.0326  - too high
   8     62.1040      7.7630      8.2482      8.0056     64.0895  - too high
   9     62.1040      7.7630      8.0056      7.8843     62.1621  - too high
  10     62.1040      7.7630      7.8843      7.8236     61.2095  - too low
  11     62.1040      7.8236      7.8843      7.8540     61.6849  - too low
  12     62.1040      7.8540      7.8843      7.8691     61.9233  - too low
  13     62.1040      7.8691      7.8843      7.8767     62.0426  - too low
  14     62.1040      7.8767      7.8843      7.8805     62.1024  - too low
  15     62.1040      7.8805      7.8843      7.8824     62.1323  - too high
  16     62.1040      7.8805      7.8824      7.8815     62.1173  - too high
  17     62.1040      7.8805      7.8815      7.8810     62.1098  - too high
  18     62.1040      7.8805      7.8810      7.8807     62.1061  - too high
  19     62.1040      7.8805      7.8807      7.8806     62.1042  - too high
  20     62.1040      7.8805      7.8806      7.8806     62.1033  - too low
  21     62.1040      7.8806      7.8806      7.8806     62.1038  - too low
  22     62.1040      7.8806      7.8806      7.8806     62.1040  - too high
  23     62.1040      7.8806      7.8806      7.8806     62.1039  - too high
sqrt(62.1040) = 7.8806

Pour 49 personnes:

pax> sqrt 49
Step      Number         Low        High         Mid      Square    Result
   1     49.0000      0.0000     49.0000     24.5000    600.2500  - too high
   2     49.0000      0.0000     24.5000     12.2500    150.0625  - too high
   3     49.0000      0.0000     12.2500      6.1250     37.5156  - too low
   4     49.0000      6.1250     12.2500      9.1875     84.4102  - too high
   5     49.0000      6.1250      9.1875      7.6562     58.6182  - too high
   6     49.0000      6.1250      7.6562      6.8906     47.4807  - too low
   7     49.0000      6.8906      7.6562      7.2734     52.9029  - too high
   8     49.0000      6.8906      7.2734      7.0820     50.1552  - too high
   9     49.0000      6.8906      7.0820      6.9863     48.8088  - too low
  10     49.0000      6.9863      7.0820      7.0342     49.4797  - too high
  11     49.0000      6.9863      7.0342      7.0103     49.1437  - too high
  12     49.0000      6.9863      7.0103      6.9983     48.9761  - too low
  13     49.0000      6.9983      7.0103      7.0043     49.0598  - too high
  14     49.0000      6.9983      7.0043      7.0013     49.0179  - too high
  15     49.0000      6.9983      7.0013      6.9998     48.9970  - too low
  16     49.0000      6.9998      7.0013      7.0005     49.0075  - too high
  17     49.0000      6.9998      7.0005      7.0002     49.0022  - too high
  18     49.0000      6.9998      7.0002      7.0000     48.9996  - too low
  19     49.0000      7.0000      7.0002      7.0001     49.0009  - too high
  20     49.0000      7.0000      7.0001      7.0000     49.0003  - too high
  21     49.0000      7.0000      7.0000      7.0000     49.0000  - too low
  22     49.0000      7.0000      7.0000      7.0000     49.0001  - too high
  23     49.0000      7.0000      7.0000      7.0000     49.0000  - too high
sqrt(49.0000) = 7.0000
37
paxdiablo

Une méthode simple (mais pas très rapide) pour calculer la racine carrée de X:

squareroot(x)
    if x<0 then Error
    a = 1
    b = x
    while (abs(a-b)>ErrorMargin) 
        a = (a+b)/2
        b = x/a
    endwhile
    return a;

Exemple: racine carrée (70000)

    a       b
    1   70000
35001       2
17502       4
 8753       8
 4381      16
 2199      32
 1116      63
  590     119
  355     197
  276     254
  265     264

Comme vous pouvez le constater, il définit une limite supérieure et une limite inférieure pour la racine carrée et réduit la limite jusqu'à ce que sa taille soit acceptable.

Il existe des méthodes plus efficaces, mais celle-ci illustre le processus et est facile à comprendre.

Méfiez-vous simplement de définir la valeur 1 sur Errormargin si vous utilisez des entiers, sinon vous avez une boucle infinie.

15
Toon Krijthe

Permettez-moi de souligner une méthode extrêmement intéressante pour calculer une racine carrée inverse 1/sqrt (x), qui est une légende du monde du game design, car elle est incroyablement rapide. Ou attendez, lisez le post suivant:

http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/

PS: Je sais que vous voulez juste la racine carrée mais l'élégance de tremblement de terre a vaincu toute résistance de ma part :)

En passant, l'article mentionné ci-dessus parle également de l'approximation ennuyeuse de Newton-Raphson quelque part.

13

Bien sûr, c'est approximatif. C’est ainsi que fonctionnent les mathématiques avec des nombres à virgule flottante.

Quoi qu'il en soit, la méthode standard est avec la méthode de Newton . C'est à peu près la même chose que d'utiliser la série de Taylor, l'inverse qui me vient immédiatement à l'esprit.

9
jrockway

Calculer une racine carrée avec une précision arbitraire en Python

#!/usr/bin/env python
import decimal

def sqrt(n):
    assert n > 0
    with decimal.localcontext() as ctx:
        ctx.prec += 2 # increase precision to minimize round off error
        x, prior = decimal.Decimal(n), None
        while x != prior: 
            prior = x
            x = (x + n/x) / 2 # quadratic convergence 
    return +x # round in a global context


decimal.getcontext().prec = 80 # desirable precision
r = sqrt(12345)
print r
print r == decimal.Decimal(12345).sqrt()

Sortie:

111.10805551354051124500443874307524148991137745969772997648567316178259031751676
True
9
jfs

J'ai trouvé un excellent article sur Integer Square Roots .

Ceci est une version légèrement améliorée qu’elle présente ici:

unsigned long sqrt(unsigned long a){
    int i;
    unsigned long rem = 0;
    unsigned long root = 0;
    for (i = 0; i < 16; i++){
        root <<= 1;
        rem = (rem << 2) | (a >> 30);
        a <<= 2;
        if(root < rem){
            root++;
            rem -= root;
            root++;
        }
    }
    return root >> 1;
}
6
Egon

C'est une question d'entretien fréquemment posée par Facebook, etc. Je ne pense pas que ce soit une bonne idée d'utiliser la méthode de Newton dans une interview. Et si l'intervieweur vous demandait le mécanisme de la méthode de Newton sans vraiment le comprendre?

J'ai fourni une solution de recherche binaire en Java que tout le monde peut comprendre.

public int sqrt(int x) {

    if(x < 0) return -1;
    if(x == 0 || x == 1) return x;

    int lowerbound = 1;
    int upperbound = x;
    int root = lowerbound + (upperbound - lowerbound)/2;

    while(root > x/root || root+1 <= x/(root+1)){
        if(root > x/root){
            upperbound = root;
        } else {
            lowerbound = root;
        }
        root = lowerbound + (upperbound - lowerbound)/2;
    }
    return root;
}

Vous pouvez tester mon code ici: leetcode: sqrt (x)

6
ChuanRocks

Voici un moyen d'obtenir une racine carrée en utilisant la trigonométrie. Ce n'est pas l'algorithme le plus rapide par un long shot, mais c'est précis. Le code est en javascript:

var n = 5; //number to get the square root of
var icr = ((n+1)/2); //intersecting circle radius
var sqrt = Math.cos(Math.asin((icr-1)/icr))*icr; //square root of n
alert(sqrt);
4
squarcle

Il existe un algorithme que j'ai étudié à l'école et que vous pouvez utiliser pour calculer des racines carrées exactes (ou une précision arbitrairement grande si la racine est un nombre irrationnel). Il est nettement plus lent que les algorithmes de Newton mais il est exact… .. Disons que vous voulez calculer la racine carrée de 531.3025

La première chose à faire est de diviser votre nombre à partir du point décimal en groupes de 2 chiffres:
{5} {31}. {30} {25}
Ensuite:
1) Trouvez la racine carrée la plus proche du premier groupe qui soit plus petite ou égale à la racine carrée réelle du premier groupe: sqrt ({5})> = 2. Cette racine carrée est le premier chiffre de votre réponse finale. Notons les chiffres que nous avons déjà trouvés de notre dernière racine carrée sous la forme B. Donc, pour le moment, B = 2.
2) Calculez ensuite la différence entre {5} et B ^ 2: 5 - 4 = 1.
3) Pour tous les groupes de 2 chiffres suivants, procédez comme suit:
Multipliez le reste par 100, puis ajoutez-le au second groupe: 100 + 31 = 131.
Trouver X - chiffre suivant de votre racine, tel que 131> = ((B * 20) + X) * X. X = 3. 43 * 3 = 129 <131. Maintenant, B = 23. En outre, comme vous n'avez plus de groupes à 2 chiffres à gauche des points décimaux, vous avez trouvé tous les chiffres entiers de votre racine finale.
4) Répétez la même chose pour {30} et {25}. Donc vous avez:
{30}: 131 - 129 = 2. 2 * 100 + 30 = 230> = (23 * 2 * 10 + X) * X -> X = 0 -> B = 23,0 
{25}: 230 - 0 = 230. 230 * 100 + 25 = 23025. 23025> = (230 * 2 * 10 + X) * X -> X = 5 -> B = 23,05 
Résultat final = 23.05.
L'algorithme semble compliqué de cette façon, mais il est beaucoup plus simple de le faire sur papier en utilisant la même notation que celle utilisée pour la "division longue" que vous avez étudiée à l'école, sauf que vous ne faites pas la division mais que vous calculez le carré. racine.

4
Eugen

La première chose qui me vient à l’esprit est la suivante: c’est un bon endroit pour utiliser la recherche binaire (inspiré par cet excellent tutoriels .)

Pour trouver la racine carrée de vaule, nous recherchons la number dans (1..value) où le prédicteur.__ est vrai pour la première fois. Le prédicteur que nous choisissons est number * number - value > 0.00001.

double square_root_of(double value)
{
     assert(value >= 1);
     double lo = 1.0;
     double hi = value;

     while( hi - lo > 0.00001)
     {
          double mid = lo + (hi - lo) / 2 ;
          std::cout << lo << "," << hi << "," << mid << std::endl;
          if( mid * mid - value > 0.00001)    //this is the predictors we are using 
          {
              hi = mid;
          } else {
              lo = mid;
          }

     }

    return lo;
 }
4
pierrotlefou
// Fastest way I found, an (extreme) C# unrolled version of:
// http://www.hackersdelight.org/hdcodetxt/isqrt.c.txt         (isqrt4)

// It's quite a lot of code, basically a binary search (the "if" statements)
// followed by an unrolled loop (the labels).
// Most important: it's fast, twice as fast as "Math.Sqrt".
// On my pc: Math.Sqrt ~35 ns, sqrt <16 ns (mean <14 ns)

private static uint sqrt(uint x)
{
    uint y, z;
    if (x < 1u << 16)
    {
        if (x < 1u << 08)
        {
            if (x < 1u << 04) return x < 1u << 02 ? x + 3u >> 2 : x + 15u >> 3;
            else
            {
                if (x < 1u << 06)
                { y = 1u << 03; x -= 1u << 04; if (x >= 5u << 02) { x -= 5u << 02; y |= 1u << 02; } goto L0; }
                else
                { y = 1u << 05; x -= 1u << 06; if (x >= 5u << 04) { x -= 5u << 04; y |= 1u << 04; } goto L1; }
            }
        }
        else                                             // slower (on my pc): .... y = 3u << 04; } goto L1; }
        {
            if (x < 1u << 12)
            {
                if (x < 1u << 10)
                { y = 1u << 07; x -= 1u << 08; if (x >= 5u << 06) { x -= 5u << 06; y |= 1u << 06; } goto L2; }
                else
                { y = 1u << 09; x -= 1u << 10; if (x >= 5u << 08) { x -= 5u << 08; y |= 1u << 08; } goto L3; }
            }
            else
            {
                if (x < 1u << 14)
                { y = 1u << 11; x -= 1u << 12; if (x >= 5u << 10) { x -= 5u << 10; y |= 1u << 10; } goto L4; }
                else
                { y = 1u << 13; x -= 1u << 14; if (x >= 5u << 12) { x -= 5u << 12; y |= 1u << 12; } goto L5; }
            }
        }
    }
    else
    {
        if (x < 1u << 24)
        {
            if (x < 1u << 20)
            {
                if (x < 1u << 18)
                { y = 1u << 15; x -= 1u << 16; if (x >= 5u << 14) { x -= 5u << 14; y |= 1u << 14; } goto L6; }
                else
                { y = 1u << 17; x -= 1u << 18; if (x >= 5u << 16) { x -= 5u << 16; y |= 1u << 16; } goto L7; }
            }
            else
            {
                if (x < 1u << 22)
                { y = 1u << 19; x -= 1u << 20; if (x >= 5u << 18) { x -= 5u << 18; y |= 1u << 18; } goto L8; }
                else
                { y = 1u << 21; x -= 1u << 22; if (x >= 5u << 20) { x -= 5u << 20; y |= 1u << 20; } goto L9; }
            }
        }
        else
        {
            if (x < 1u << 28)
            {
                if (x < 1u << 26)
                { y = 1u << 23; x -= 1u << 24; if (x >= 5u << 22) { x -= 5u << 22; y |= 1u << 22; } goto La; }
                else
                { y = 1u << 25; x -= 1u << 26; if (x >= 5u << 24) { x -= 5u << 24; y |= 1u << 24; } goto Lb; }
            }
            else
            {
                if (x < 1u << 30)
                { y = 1u << 27; x -= 1u << 28; if (x >= 5u << 26) { x -= 5u << 26; y |= 1u << 26; } goto Lc; }
                else
                { y = 1u << 29; x -= 1u << 30; if (x >= 5u << 28) { x -= 5u << 28; y |= 1u << 28; } }
            }
        }
    }
    z = y | 1u << 26; y /= 2; if (x >= z) { x -= z; y |= 1u << 26; }
Lc: z = y | 1u << 24; y /= 2; if (x >= z) { x -= z; y |= 1u << 24; }
Lb: z = y | 1u << 22; y /= 2; if (x >= z) { x -= z; y |= 1u << 22; }
La: z = y | 1u << 20; y /= 2; if (x >= z) { x -= z; y |= 1u << 20; }
L9: z = y | 1u << 18; y /= 2; if (x >= z) { x -= z; y |= 1u << 18; }
L8: z = y | 1u << 16; y /= 2; if (x >= z) { x -= z; y |= 1u << 16; }
L7: z = y | 1u << 14; y /= 2; if (x >= z) { x -= z; y |= 1u << 14; }
L6: z = y | 1u << 12; y /= 2; if (x >= z) { x -= z; y |= 1u << 12; }
L5: z = y | 1u << 10; y /= 2; if (x >= z) { x -= z; y |= 1u << 10; }
L4: z = y | 1u << 08; y /= 2; if (x >= z) { x -= z; y |= 1u << 08; }
L3: z = y | 1u << 06; y /= 2; if (x >= z) { x -= z; y |= 1u << 06; }
L2: z = y | 1u << 04; y /= 2; if (x >= z) { x -= z; y |= 1u << 04; }
L1: z = y | 1u << 02; y /= 2; if (x >= z) { x -= z; y |= 1u << 02; }
L0: return x > y ? y / 2 | 1u : y / 2;
}
3
P_P

utiliser la recherche binaire

public class FindSqrt {

    public static void main(String[] strings) {

        int num = 10000;
        System.out.println(sqrt(num, 0, num));
    }

    private static int sqrt(int num, int min, int max) {
        int middle = (min + max) / 2;
        int x = middle * middle;
        if (x == num) {
            return middle;
        } else if (x < num) {
            return sqrt(num, middle, max);
        } else {
            return sqrt(num, min, middle);
        }
    }
}
2
Dheeraj Sachan

L'inverse, comme son nom l'indique, mais parfois "assez proche" est "assez proche"; une lecture intéressante quand même.

Origine de Fast InvSqrt de Quake3 ()

1
user166390

En général, la racine carrée d'un entier (comme 2, par exemple) ne peut être approchée que par seulement (non à cause de problèmes d'arithmétique en virgule flottante, mais parce que ce sont des nombres irrationnels qui ne peuvent pas être calculés exactement).

Bien sûr, certaines approximations sont meilleures que d'autres. Je veux dire, bien sûr, que la valeur 1.732 est une meilleure approximation de la racine carrée de 3 que 1.7 

La méthode utilisée par le code sur ce lien que vous avez donné fonctionne en prenant une première approximation et en l'utilisant pour calculer une approximation mieux.

Cela s'appelle la méthode de Newton et vous pouvez répéter le calcul avec chaque nouvelle approximation jusqu'à ce que soit suffisamment précis pour vous.

En fait, il y a un {doit} _ moyen de décider quand arrêter la répétition ou elle durera indéfiniment.

Généralement, vous vous arrêtez lorsque la différence entre les approximations est égale à inférieure à, une valeur que vous décidez.

EDIT: Je ne pense pas qu'il puisse y avoir une implémentation plus simple que les deux que vous avez déjà trouvées.

1
pavium

Une solution simple pouvant traiter la racine carrée flottante et la précision arbitraire à l'aide de la recherche binaire

codé en Ruby

include Math

def sqroot_precision num, precision
  upper   = num
  lower   = 0
  middle  = (upper + lower)/2.0

  while true do
    diff = middle**2 - num

    return middle if diff.abs <= precision

    if diff > 0
      upper = middle
    else diff < 0
      lower = middle
    end

    middle = (upper + lower)/2.0
  end 
end

puts sqroot_precision 232.3, 0.0000000001
0
Chihung Yu

Eh bien, il y a déjà pas mal de réponses, mais voici la mienne C'est le morceau de code le plus simple (pour moi), voici le algorithm pour cela. 

Et code en python 2.7:

from __future__ import division 
val = 81
x = 10
def sqr(data,x):
    temp = x - ( (x**2 - data)/(2*x))
    if temp == x:
        print temp
        return
    else:
        x = temp
        return sqr(data,x)
    #x =temp 
    #sqr(data,x)
sqr(val,x)
0
hubatrix

Supposons que nous essayons de trouver la racine carrée de 2 et que vous avez une estimation de 1,5. Nous dirons a = 2 et x = 1,5. Pour calculer une meilleure estimation, nous allons diviser un par x. Cela donne une nouvelle valeur y = 1,333333. Cependant, nous ne pouvons pas prendre cela comme notre prochaine estimation (pourquoi pas?). Nous devons faire la moyenne avec l'estimation précédente. Donc, notre prochaine estimation, xx sera (x + y)/2, ou 1.416666.

Double squareRoot(Double a, Double epsilon) {
    Double x = 0d;
    Double y = a;
    Double xx = 0d;

    // Make sure both x and y != 0.
    while ((x != 0d || y != 0d) && y - x > epsilon) {
        xx = (x + y) / 2;

        if (xx * xx >= a) {
            y = xx;
        } else {
            x = xx;
        }
    }

    return xx;
}

Epsilon détermine le degré de précision de l'approximation. La fonction doit renvoyer la première approximation x obtenue qui vérifie abs (x * x - a) <epsilon, où abs (x) est la valeur absolue de x.

square_root(2, 1e-6)
Output: 1.4142141342163086
0
S_R