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

Bibliothèque standard C Discussion :

Calcul de PI, optimisation 64 bits


Sujet :

Bibliothèque standard C

  1. #1
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mai 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mai 2007
    Messages : 108
    Points : 57
    Points
    57
    Par défaut Calcul de PI, optimisation 64 bits
    Bonjour,

    Tout d'abord j'espère être sur le bon forum. Ensuite, petite explication de mon code .... tout simple .... calculer PI ..... avec une précision raisonnable ...... disons 2^20 digits par ex (oui oui 1 millions de chiffres après la virgule)

    En réalité, le but pour moi, c'est la manipulation de chiffre en virsule flottantes avec une grande précision (au moins 2^10 chiffres après la virgule)
    Mais aussi et surtout me familiariser avec la compilation pour une archi 64bits.
    Pour avoir un but, je me suis mis en tête de faire un équivalent Linux à SuperPI.
    Bien qu'un équivalent existe, celui ci n'utilise qu'un seul core (et compiler en 32bits).

    Passons au choses sérieuses. Pour l'algorithme, j'ai décidé de prendre celui de Gauss–Legendre (celui utilisé par ex par le logiciel Windows SuperPI)

    J'ai réussi à compiler l'algorithme. Par contre, la précision est rédicule 16chiffres après la virgule

    Voici la boucle de calcul et la déclaration des variables

    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
     
    	double an,bn,tn,pn,an1,bn1,tn1,pn1,pi;
    	double	tmp;
    	int		i,prec;
    ...
    {
    		/* Calcul de PI */
    		an1=(an+bn)/2;
    		bn1=sqrt(an*bn);
    		tmp=((double)(an)-(double)(an1));
    		tmp=(double)(tmp)*(double)(tmp);
    		tn1=(double)(tn)-(double)(pn)*(double)(tmp);
    		pn1=2*pn;
    		pi=((an1+bn1)*(an1+bn1))/(4*tn1);
     
    		/* Calcul de la précision */
    		tmp=an1-bn1;
     
    		prec=0;
    		do
    		{
    			tmp*=10;
    			prec++;
    		} while (tmp<1);
     
    		printf("pi : %.50lf\n",pi);
     
     
    		an=an1;
    		bn=bn1;
    		tn=tn1;
    		pn=pn1;
     
    		i++;
    	}
    Passer 3 itérations, la valeur de pi ne change plus

    Je pense que cela provient du fait que mes double n'ont pas une précision suffisante. Et pour enfoncer le clou, j'imagine qu'il va me falloir reprogrammer les fonctions de calcul des multiplications, de racine carré et autre non ?

    Mais pour l'instant, j'aimerais savoir comment manipuler des float avec une précision gigantesques

    Merci pour votre aide

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Je ne vois pas ce que le 64 bits changera ici, vu que tu n'utilises pratiquement que des double, qui de toute façon sont déjà sur 64 bits...

  3. #3
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 949
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 949
    Points : 5 663
    Points
    5 663
    Par défaut
    Kae,

    Joli projet, mais il implique d'écrire toute une bibliothèque de calcul multi-précision.

    Ce n'est pas très compliqué, mais ça ne se fait pas comme ça sur le coin de la table, en particulier pour l'optimisation.

  4. #4
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Citation Envoyé par elekaj34 Voir le message
    Et pour enfoncer le clou, j'imagine qu'il va me falloir reprogrammer les fonctions de calcul des multiplications, de racine carré et autre non ?
    Si.

  5. #5
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mai 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mai 2007
    Messages : 108
    Points : 57
    Points
    57
    Par défaut
    Merci pour vos réponses

    Pour le 64bits, en effet cela ne changera pas grand chose. Par ailleurs, je suis passé en long double (j'ai un peu amélioré la précision)

    Le souci, c'est que je n'arrive pas à dépasser des précisions de quelques dizaines de chiffres (après la virgule)
    Je vais voir si il n'y a pas moyen de travailler sur des entiers (encore qu'avec des long double, je devrais pouvoir arriver à calculer jusqu'à plusieurs centaines de chiffres après la virgules)

    Autre chose, actuellement, un seul core est utilisé lors du calcul. Bien que j'ai déjà fait des applis multithreadées, je vois mal comment répartir le calcul sur plusieurs core.
    Une idée ?

    une bibliothèque de calcul multi-précision.
    Qu'entends tu par multi précision ?

    Merci pour votre aide

  6. #6
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Il veut dire des lib pour travailler avec des nombres arbitrairement grands, comme GMP.

    Pour ce qui est du calcul parallèle, si tes threads peuvent effectivement travailler en parallèle, l'OS devrait automatiquement les dispatcher sur deux CPUs différents. Si ce n'est pas le cas c'est que tu t'es mal débrouillé et tes deux threads ne peuvent jamais (ou quasiment jamais) travailler en parallèle. C'est le cas par exemple si un de tes threads a constament besoin d'un résultat produit par l'autre thread.

  7. #7
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par elekaj34 Voir le message
    encore qu'avec des long double, je devrais pouvoir arriver à calculer jusqu'à plusieurs centaines de chiffres après la virgules
    Tu m'as l'air de confondre l'intervalle et la precision. Un long double fait 64, 80 ou 128 bits (rien de normalise, c'est simplement les cas que je connais). Meme en comptant 3 bits par chiffre decimal (ce qui est deja sur-estimer la precision qu'on optiendra) et en oubliant qu'il faut stocker l'exposant et le signe (encore des sources de surestimations), ca fait 22, 27 ou 43 chiffres, certainement pas des centaines.

    Autre chose, actuellement, un seul core est utilisé lors du calcul. Bien que j'ai déjà fait des applis multithreadées, je vois mal comment répartir le calcul sur plusieurs core.
    En deux threads, j'en aurais un qui calcule a_n+1, t_n+1, p_n+1 et un qui calcule b_n+1. En plus je vois rien d'evident.

    Qu'entends tu par multi précision ?
    Pour atteindre une precision de l'ordre du million de chiffres, il faudra que tu te batisses toi-meme tes primitives de calculs, ou que tu utilises des bibliotheques toutes faites comme gmp.

  8. #8
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 949
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 949
    Points : 5 663
    Points
    5 663
    Par défaut
    Sie,
    Citation Envoyé par elekaj34 Voir le message
    Le souci, c'est que je n'arrive pas à dépasser des précisions de quelques dizaines de chiffres (après la virgule)
    Je vais voir si il n'y a pas moyen de travailler sur des entiers (encore qu'avec des long double, je devrais pouvoir arriver à calculer jusqu'à plusieurs centaines de chiffres après la virgules)
    Tu devrais tout de même te renseigner sur les précisions des types que tu veux utiliser.

    Tes remarques me conduisent à penser que tu n'es pas prêt pour un tel projet.

  9. #9
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par droggo Voir le message
    Tes remarques me conduisent à penser que tu n'es pas prêt pour un tel projet.
    Citation Envoyé par elekaj34 Voir le message
    .... calculer PI ..... avec une précision raisonnable ...... disons 2^20 digits par ex (oui oui 1 millions de chiffres après la virgule)

    Es-tu sûr que c'est 2^20 digits ?? et pas 20 chiffres après la virgule ??

  10. #10
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mai 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mai 2007
    Messages : 108
    Points : 57
    Points
    57
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    Tu m'as l'air de confondre l'intervalle et la precision. Un long double fait 64, 80 ou 128 bits (rien de normalise, c'est simplement les cas que je connais). Meme en comptant 3 bits par chiffre decimal (ce qui est deja sur-estimer la precision qu'on optiendra) et en oubliant qu'il faut stocker l'exposant et le signe (encore des sources de surestimations), ca fait 22, 27 ou 43 chiffres, certainement pas des centaines.
    C'est fort probable que j'emploie les mauvais termes c'est certainement aussi pourquoi on se comprend mal.

    Petit exemple (idiot mais c'est pour l'exemple):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int main(void)
    {
    	long double val;
     
      	val=1e-150*1e-150;
      	printf("%Lf\n",val);
      	return;
    }
    me retourne
    0.00000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    0000000000001
    (vous pouvez compter, il y a 300 chiffres après la virgule)

    Voici ce que j'appelle une précision de 300 chiffres. Alors après documentation, cela n'a rien a voire avec une précision.

    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    En deux threads, j'en aurais un qui calcule a_n+1, t_n+1, p_n+1 et un qui calcule b_n+1. En plus je vois rien d'evident.
    Pour l'instant je vais me concentrer sur le calcul. Pour le multithread, on verra plus tard.


    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    Pour atteindre une precision de l'ordre du million de chiffres, il faudra que tu te batisses toi-meme tes primitives de calculs, ou que tu utilises des bibliotheques toutes faites comme gmp.
    Je vais potasser cette lib et me fiamiliariser avec elle.
    Citation Envoyé par droggo Voir le message
    Sie,

    Tu devrais tout de même te renseigner sur les précisions des types que tu veux utiliser.

    Tes remarques me conduisent à penser que tu n'es pas prêt pour un tel projet.
    Cf plus haut.


    Citation Envoyé par souviron34 Voir le message
    Es-tu sûr que c'est 2^20 digits ?? et pas 20 chiffres après la virgule ??
    C'est comme ceci que c'est indiqué dans la doc de superpi.
    Number of digits after the decimal point (10 generate 2 ^ 10 digits after the decimal point)

  11. #11
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par elekaj34 Voir le message
    C'est comme ceci que c'est indiqué dans la doc de superpi.
    Ben ça me semble pas clair....

    Ce qu'il y a avant la parenthèse indique bien le nombre de chiffres après la virgule (10). (ce qui n'est pas 2^10 chiffres, mais combinaisons possibles)

    La soi-disant explication dans la parenthèse est contradictoire...

    J'aurais donc tendance à penser que ce qui est désiré est 10 (ou 20) chiffres après la virgule. C'est tout.

  12. #12
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,
    Citation Envoyé par elekaj34 Voir le message
    C'est fort probable que j'emploie les mauvais termes c'est certainement aussi pourquoi on se comprend mal.
    Voici ce que j'appelle une précision de 300 chiffres. Alors après documentation, cela n'a rien a voire avec une précision.
    Le nombres flottant sont à précision variable.
    Exemple : le float (32bits) :
    1 bit de signe,
    8 bits exposant
    23 bits de mantisse.

    la valeur du flottant s'écrit comme ça :
    f = (-1)^s * 2 ^ (exp - 127) * (1 + man/2^24).

    En gros, l'exposant permet de situer le flottant en terme de puissance de deux :
    exposant = 126 -> flottant entre .5 et 1
    exposant = 127 -> flottant entre 1 et 2
    exposant = 128 -> flottant entre 2 et 4
    exposant = 129 -> flottant entre 4 et 8

    la mantisse permet de se situer dans cet intervalle.

    Donc entre deux puissances de 2 successives, le flottant ne pourra prendre que 16777216 (2^24) valeurs.

    Ainsi, entre 1 et 2, il y a au mieux 7 décimales significatives.
    Ainsi, entre 2 et 4, il n'y en a que 6.

    Plus l'exposant est proche de 0, plus la précision apparente est grande. voilà pourquoi l'exemple donné donne l'impression d'être si juste.

    mais si on tape :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <stdio.h>
     
    int main(void)
    {
        double val = 1e-10;
        printf("%g\n",val);
     
        val += 1.;
        printf("%g\n",val);
     
        return 0;
    }
    on a des surprises.

    --> IEEE754

  13. #13
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mai 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mai 2007
    Messages : 108
    Points : 57
    Points
    57
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Ben ça me semble pas clair....

    Ce qu'il y a avant la parenthèse indique bien le nombre de chiffres après la virgule (10). (ce qui n'est pas 2^10 chiffres, mais combinaisons possibles)

    La soi-disant explication dans la parenthèse est contradictoire...

    J'aurais donc tendance à penser que ce qui est désiré est 10 (ou 20) chiffres après la virgule. C'est tout.
    Je conteste pas, mais pour ./pi 20 (donc 1millions de chiffres), il faut quand même 22s (donc çà ne peut pas être 20 chiffres)

    Pour en revenir à mon problème, j'ai bêtement voulu appliquer un algo trouvé sur Wikipédia sans chercher si cela avait déjà été fait. En cherchant un peu une mise en application du calcul de PI, j'ai trouvé le code suivant :

    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
    #include <stdio.h>
     
    int main(void)
    {
    	int p = 8400;
    	int a = 10000, b,c = p, d, e, f[p+1], g, i=0;
     
    	for ( ; b-c ; ) f[b++] = a/5;
     
    	for ( ; d = 0, g = c*2 ; c -= 14, printf("%.4d",e+d/a), e = d%a)
      	{
      		for (b = c ; d += f[b]*a, f[b] = d%--g, d /= g--, --b ; d *= b);
      		i++;
      	}
     
      	return;
    }
    le calcul est super lent, mais dans ce cas précis, on génère les 2400 premières décimales.

  14. #14
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mai 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mai 2007
    Messages : 108
    Points : 57
    Points
    57
    Par défaut
    @mabu

    Oui effectivement, c'est en relisant mes cours que j'en ai pris conscience.

    Mais je vais m'atteler à gmp

Discussions similaires

  1. Calculs sous Windows XP 64 bits
    Par DidLaw dans le forum Ordinateurs
    Réponses: 1
    Dernier message: 19/04/2010, 14h25
  2. erreur dans le calcul de nombre moyen des bits érronés
    Par princesse07 dans le forum MATLAB
    Réponses: 3
    Dernier message: 23/05/2008, 14h30
  3. Calcul d'un CRC 16 bits
    Par pinto_armindo dans le forum Programmation et administration système
    Réponses: 5
    Dernier message: 22/06/2006, 15h35
  4. [Optimisation][Fonction]calcul du nombre de jours ...
    Par m-mas dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 26/10/2005, 14h39
  5. Optimisation en c du calcul du ppcm
    Par KORTA dans le forum C
    Réponses: 3
    Dernier message: 05/09/2003, 08h23

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