IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Fonction racine carré


Sujet :

C

  1. #1
    Membre à l'essai
    Inscrit en
    Septembre 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 13
    Points : 11
    Points
    11
    Par défaut Fonction racine carré
    J'essaye de refaire la fonction sqrt Pour cela je me suis demander quel formule il faut que j'utilise , etant en terminal je ne le sais toujours pas . Bon donc je vais faire avec un peu de logique ce qui me donne ça :

    Fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    double racine( double racine )
                {
     
                double resultat = 0.000;
                double i = 0.000;
                double maximum = racine;
     
     
                for( i = 0.000 ; i < maximum ; i += 0.001 )
     
                        {
                            if( i * i == racine)
     
                            {
                                resultat = i;
     
     
                            }
     
     
                        }
     
                return resultat;
     
     
                }
    Prototype :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    double racine(double naturel);
    Main.c :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    printf("%f",racine(25));
    Malheuresement j'obtient 0.0000 au lieu de 5.00000

    Ah oui , le nombre x sera en general plus grand que la racine de x , apart si celui si est inferieur à 1 donc pour la condition je la ferai plus tard

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Pour calculer plus rapidement et plus simplement, il vaut mieux passer par les méthodes ancestrales. Tu as par exemple celle-ci : http://fr.wikipedia.org/wiki/M%C3%A9thode_de_H%C3%A9ron

  3. #3
    Membre à l'essai
    Inscrit en
    Novembre 2007
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 23
    Points : 19
    Points
    19
    Par défaut
    voilà amigos
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include <stdio.h>
    #include <math.h>
    #include <conio.h>
    double racine( double x )
                {
                double i;
     
                i=0.000;
                do
                {
                i+=0.001;
     
                }while(i*i<x);
     
     
                return i;
     
     
                }
     
                void main()
                { int ent;
                  double sqrt;
                printf("donner un entier ");
                scanf("%i",&ent);
                sqrt=racine(ent);
                printf("la racine carrée de %i est %.2f",ent,sqrt);
                getch();
                }
    fonctionnel 100% si tu comprends pas quelque choses n'hesite pas a me demander ...

  4. #4
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Je te conseille de te pencher sur la méthode classique et beaucoup plus efficace évoquée par jeroman. Si tu es en terminale, elle est à ta portée.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 377
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 377
    Points : 23 663
    Points
    23 663
    Par défaut
    Citation Envoyé par aymenet1 Voir le message
    fonctionnel 100% si tu comprends pas quelque choses n'hesite pas a me demander ...
    C'est un peu présomptueux :

    • Sur mon Core 2 Quad à 2,83 Ghz, il m'a fallu dix secondes pour que i atteigne 2767750,9674904584. Si tu voulais trouver la racine du plus grand nombre possible représentable avec un double (64 bits). Cela prendrait donc DBL_MAX ÷ 2767750.9674904584 ÷ 6 ÷ 60 ÷ 24 ÷ 365.25 années, soit : 205 818 581 907 479 461 463 410 466 691 017 217 129 174 295 660 217 585 353 873 316 935 10 583 895 465 556 118 545 809 178 392 910 646 621 189 221 477 561 271 807 007 840 365 11 27 868 396 532 752 861 115 510 232 209 269 907 478 541 557 950 849 017 030 089 280 180 75 650 652 320 555 183 125 073 391 189 973 814 214 462 500 545 051 898 146 802 766 095 968 806 074 575 629 103 353 387 359 928 320 années de calcul. À titre de comparaisons, l'univers n'est âgé que de 13 700 000 000 années ;
    • Même si tu avais la patience d'attendre, le principe d'un nombre à virgule flottante est de représenter des nombres toujours plus grands sur une même largeur de bits. Les nombres les plus petits sont alors négligés. Ton 0.001 finirait par être assimilé à un zéro et ton programme tournerait en boucle infinie ;
    • Les carrés des nombres inférieurs à 1 sont plus petits que leurs racines. Tous les nombres plus proches de zéro que 0,031623 auraient alors « 0,001 » pour solution unique !


    Il y a plusieurs manières d'extraire une racine carrée mais, étant donné qu'un ordinateur est une machine finie et soumise aux imprécisions, je trouve que le plus simple est d'utiliser l'algorithme arithmétique tel qu'il était enseigné jadis à l'école :

    http://fr.wikipedia.org/wiki/Racine_...s_carr.C3.A9es

    C'est applicable à toutes les bases, y compris la base 2 qui, comme pour la division, simplifie considérablement les étapes à mener. La complexité (et sa durée) de l'algorithme est alors uniquement fonction du nombre de bits (ici, 64).

  6. #6
    Membre à l'essai
    Inscrit en
    Novembre 2007
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 23
    Points : 19
    Points
    19
    Par défaut
    mon code n'est pas precis et il ne trouve pas les racines des reels <1 .
    je comprends Obsidian ...
    si on choisis 0.000000001 comme pas et on veux trouver la racine de 1000000000 il faut attendre une un tres grand temps ^^
    Merci pour l'explication pour les examples .

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 377
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 377
    Points : 23 663
    Points
    23 663
    Par défaut
    Citation Envoyé par aymenet1 Voir le message
    si on choisis 0.000000001 comme pas et on veux trouver la racine de 1000000000 il faut attendre une un tres grand temps ^^
    Non seulement, dans certains cas, l'âge de l'univers lui-même serait insignifiant par rapport au temps qu'il faudrait mais, comme je te le disais, il est possible qu'à partir d'une certaine valeur, ton programme entre dans une boucle infinie. Voici pour exemple un programme qui utilise float et qui compte de 1.000.000.000 (un milliard) à 1.000.000.100 (un milliard cent), soit cent tours de boucle, ce qui n'a rien d'extraordinaire. Lance-le sur ta machine et admire le résultat :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #include <stdio.h>
    #include <stdio.h>
     
    int main (void)
    {
        float x =  1000000000.0;     /* Un milliard. */
     
        while (x < 1000000100.0)
        {
            printf ("%f\n",x);
            x = x+1;                /* On ajoute 1 */
        }
     
        return 0;
    }

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $ gcc milliard.c -o milliard
    $ ./milliard
    1000000000.000000
    1000000000.000000
    1000000000.000000
    1000000000.000000
    1000000000.000000
    1000000000.000000
    1000000000.000000
    1000000000.000000
    1000000000.000000
    …

    Essaie de comprendre pourquoi.

    Merci pour l'explication pour les examples .
    À ton service.

  8. #8
    Membre à l'essai
    Inscrit en
    Novembre 2007
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 23
    Points : 19
    Points
    19
    Par défaut
    le code fonctionne avec le type double mais pas avec le type float .
    je sais que le double et plus grand que le type float je pense que 1000000000 depasse le float mais lorsque j'ai cherché un peu sur internet pour voir l'intervalle du type float j'ai trouvé float |(reel) flottant de 3.4*10-38 à 3.4*1038 dont 5 chiffres apres la virgule donc il peut suffisament contenir un million ...

  9. #9
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 377
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 377
    Points : 23 663
    Points
    23 663
    Par défaut
    Citation Envoyé par aymenet1 Voir le message
    le code fonctionne avec le type double mais pas avec le type float .
    je sais que le double et plus grand que le type float je pense que 1000000000 depasse le float mais lorsque j'ai cherché un peu sur internet pour voir l'intervalle du type float j'ai trouvé float |(reel) flottant de 3.4*10-38 à 3.4*1038 dont 5 chiffres apres la virgule donc il peut suffisament contenir un million ...
    Un milliard !

    « 3,4 × 10 ^ 38 », ça fait « 340 000 000 000 000 000 000 000 000 000 000 000 000 » soit trois cent quarante milliards de milliards de milliards de milliards ». Il y a donc largement de quoi faire tenir un milliard dans un simple float 32 bits. D'autant plus que, si le programme tourne en boucle, il affiche quand même bien « 1000000000 » à l'écran. Donc, ce nombre tient dans un float, et heureusement !

    Le problème est plus subtil que ça. Peux-tu le voir ?

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 23
    Points : 22
    Points
    22
    Par défaut
    Je propose ça comme code, le principe etant :
    Dans un premier temps chercher à encadrer la racine , meme si l'encadrement est tres large.
    Dans un second temps, reduire l'intervalle par dichotomies successives.
    C'est sans doute un peu plus long que la méthode de héron mais ca reste dans un temps tres raisonnable. le seul problème est la présision pour les racines des grands nombres.
    Par contre il n'y a aucune difficulté à comprendre le principe, contrairement a la méthode de Héron.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #include<stdio.h>
    #define PRECISION 0.0000000000001
    #include<stdlib.h>
    ouble SQRT(double d)
    {   double tmpinf=0,tmpsup=1,mid;
        if (d<0)
        {   printf("racine d'un nombre negatif\n");
            exit(1);
        }
        if (d==0.)
        {   return 0.;
        }   
     
     
        while((1-tmpinf/tmpsup)>PRECISION)
        {   mid=(tmpinf+tmpsup)/2;
            if (tmpsup*tmpsup<d)
            {   tmpsup=2*tmpsup;
            }
            else if(mid*mid<d)
            {   tmpinf=mid;
            }
            else
            {   tmpsup=mid;
            }
     
            printf("min = %.20f max = %.20f\n",tmpinf,tmpsup);
        }
        return mid;
    }
    int main (int argc,char** argv)
    {   double d;
     
        if(argc==0)
        {   printf("pas d'argument");
            return 1;
        }
        d=atof(argv[1]);
        printf("sqrt( %.20f) = %.20f\n",d,SQRT(d));
        return 0;
    }

  11. #11
    Membre à l'essai
    Inscrit en
    Novembre 2007
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 23
    Points : 19
    Points
    19
    Par défaut
    pour le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #include <stdio.h>
    #include <stdio.h>
     
    int main (void)
    {
        float x =  1000000000.0;     /* Un milliard. */
     
        while (x < 1000000100.0)
        {
            printf ("%f\n",x);
            x = x+1;                /* On ajoute 1 */
        }
     
        return 0;
    }
    j'ai pas pu resoude le proble de ce code car je suis un debutant ,
    j'aimerai qu'on mexplique logiquement ce qui se passe .
    je pense que c'est une histoire de logique rien d'autre et merci encore Obsidian .

  12. #12
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Jette un coup d'oeil à cette discussion
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  13. #13
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 377
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 377
    Points : 23 663
    Points
    23 663
    Par défaut
    Citation Envoyé par aymenet1 Voir le message
    j'aimerai qu'on mexplique logiquement ce qui se passe
    Déjà, un float est codé sur 32 bits, donc, quelle que soit l'interprétation que l'on en fait, tu ne pourras pas représenter plus de 4.294.967.296 nombres différents. Rapporté aux 2 × 3,4⋅10^38 nombres théoriques, limites du float, on comprend que l'espace va être « plein de vide » et que la majorité des valeurs ne pourront pas être codées.

    En fait, un nombre à virgule flottante, ce n'est ni plus ni moins que la notation scientifique portée en informatique. Exemple en décimal, très répandu à l'école : deux chiffres après la virgule :

    1,02⋅10^0 = 1,02.

    Tu as ici une précision au centième. Ta mantisse contient exactement deux chiffres, ce qui ne varie jamais. Pourtant, en jouant sur l'ordre de grandeur (l'exposant), tu peux représenter des nombres astronomiques. Le nombre de chiffres après la virgule définit donc leur précision. Tu n'es pas à un millimètre près si tu mesure la distance Terre-Lune, par exemple. Par conséquent :

    1,02⋅10^4 = 10200
    1,03⋅10^4 = 10300

    Tu as ici une précision à la centaine. Tu peux coder 10200 ou 10300, mais en aucun cas 10250 ni même, a fortiori, 10201, car il te faudrait plus de chiffres après la virgule pour le faire.

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 23
    Points : 22
    Points
    22
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Déjà, un float est codé sur 32 bits, donc, quelle que soit l'interprétation que l'on en fait, tu ne pourras pas représenter plus de 4.294.967.296 nombres différents. Rapporté aux 2 × 3,4⋅10^38 nombres théoriques, limites du float, on comprend que l'espace va être « plein de vide » et que la majorité des valeurs ne pourront pas être codées.

    En fait, un nombre à virgule flottante, ce n'est ni plus ni moins que la notation scientifique portée en informatique. Exemple en décimal, très répandu à l'école : deux chiffres après la virgule :

    1,02⋅10^0 = 1,02.

    Tu as ici une précision au centième. Ta mantisse contient exactement deux chiffres, ce qui ne varie jamais. Pourtant, en jouant sur l'ordre de grandeur (l'exposant), tu peux représenter des nombres astronomiques. Le nombre de chiffres après la virgule définit donc leur précision. Tu n'es pas à un millimètre près si tu mesure la distance Terre-Lune, par exemple. Par conséquent :

    1,02⋅10^4 = 10200
    1,03⋅10^4 = 10300

    Tu as ici une précision à la centaine. Tu peux coder 10200 ou 10300, mais en aucun cas 10250 ni même, a fortiori, 10201, car il te faudrait plus de chiffres après la virgule pour le faire.
    j'ai effectivement rencontré ce probleme:
    1) si je met un nombre trop petit dans mon champ précision je me met a boucler infiniment (parce que ma demi-somme reste egale a la borne qu'elle doit remplacer, sans pour autant etre la racine exacte recherchee)
    2) en remplacant les doubles par des long double et avec des valeurs de precision trop faible , je me rend compte que ma racine converge vers une valeur fausse, particulierement visible pour des grands nombres.

  15. #15
    Membre à l'essai
    Inscrit en
    Novembre 2007
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 23
    Points : 19
    Points
    19
    Par défaut
    bonne explication diogene merci beaucoup

Discussions similaires

  1. [Débutant] Tracer d'une fonction racine carrée
    Par ktolajumel dans le forum MATLAB
    Réponses: 5
    Dernier message: 30/06/2013, 17h39
  2. Fonction racine carrée entière
    Par kimikou dans le forum Général Python
    Réponses: 4
    Dernier message: 01/02/2009, 16h06
  3. fonction racine carré
    Par goldensun dans le forum Débuter
    Réponses: 14
    Dernier message: 29/10/2008, 11h50
  4. Utilisation de la fonction racine carré
    Par derf_r dans le forum Access
    Réponses: 3
    Dernier message: 23/11/2005, 16h30
  5. Racine carrée
    Par SteelBox dans le forum Mathématiques
    Réponses: 5
    Dernier message: 23/11/2002, 17h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo