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 :

calcul de nombre infiniment grand


Sujet :

C

  1. #1
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    178
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 178
    Points : 61
    Points
    61
    Par défaut calcul de nombre infiniment grand
    Bonjour à tous,

    je vous écrit car je recherche un méthode qui permet de faire des calcul avec des nombres infiniment grand.
    J'ai vu sur le net qu'on pouvais utilisé les char pour faire des calcule.
    Il y a t'il d'autre méthode? algorithme? qui permet de faire cela.

    merci d'avance.
    jerem721

  2. #2
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Infiniment grands (= l'infini mathématique) ou justes très grands (milliards de milliards ... de milliards) ? Dans le deuxième cas, il y a des bibliothèques comme GMP qui sont faites pour. Du point de vue algorithmique, il faut en effet représenter les nombres avec des chaînes de caractères et faire les calculs sur ces chaînes.

  3. #3
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    178
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 178
    Points : 61
    Points
    61
    Par défaut
    oui serait pour des nombre de l'ordre du milliard de milliard (tout ce qui ne rentre pas dans un int en faite)
    c'est quoi la méthode a utiliser avec les char car je comprend pas trop en faire comme on peut calculer avec des char :s

  4. #4
    Membre expérimenté Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    887
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 887
    Points : 1 531
    Points
    1 531
    Par défaut
    Citation Envoyé par jerem721 Voir le message
    des nombres infiniment grand.
    INFINIMENT ? Tu vas avoir du mal à trouver.

    Si tu peux te contenter seulement de nombre très grands, il existe des bibliothèques.

    Regarde ici: http://gmplib.org/

    [edit]Grillé par un modérateur qui poste plus vite que son ombre[/edit]

  5. #5
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    Autrement si tout tes nombres sont du même ordre de grandeur, tu peux changer d'unité/d'échelle pour que tes nombres tiennent dans un int.

    Par exemple pour une application manipulant des distance/longueurs. On peux très bien choisir que l'unité stocké dans un int sera le ..., millimètres, mètres, kilomètres, ....

    le millimètre sera plutôt pour des plan type menuiserie ...
    le mètre sera plutôt utilisé pour les plans cadastraux
    les kilomètres pour les plans d'autoroute.

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    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 401
    Points : 23 780
    Points
    23 780
    Par défaut
    Hello,

    Citation Envoyé par jerem721 Voir le message
    oui serait pour des nombre de l'ordre du milliard de milliard (tout ce qui ne rentre pas dans un int en faite)
    c'est quoi la méthode a utiliser avec les char car je comprend pas trop en faire comme on peut calculer avec des char :s
    En fait, calculer avec des « char » n'est pas la méthode la plus efficace. Le mieux reste encore d'utiliser les types natifs de ta machine (int) et de faire de l'arithmétique avec, comme sur papier. Ce n'est pas forcément très difficile en soi, mais cela demande d'être TRÈS soigneux, et c'est quand même beaucoup de boulot, car il faut ré-implémenter toutes les opérations arithmétiques de base et gérer l'allocation de la mémoire avec.

    L'idée, donc, est de considérer que FFFFFFFFh + FFFFFFFFh font 1FFFFFFFEh. Donc la somme de deux nombres 32 bits tient au maximum sur 33. Tu peux donc obtenir le résultat un registre du même format que les opérandes et gérer la retenue à côté.

    Pour la multiplication, le produit de deux nombres 32 bits tient sur 64 bits au maximum (le double de la taille des opérandes). Dans l'absolu, tu pourrais donc obtenir le résultat du produit de deux long dans un long long. Tu peux alors « poser » les 32 bits de poids faible et « retenir » les 32 autres.

    C'est de la même façon que, sur papier, lorsque tu multiplies deux nombres de 1 chiffre, par exemple 8 × 9, le résultat tient au maximum sur deux chiffres, ici 72. Tu poses alors « 2 » et tu retiens « 7 ».

    Si tu considères que tu travailles en bases 4294967925, alors chaque chiffre unique tient exactement sur 32 bits et les règles de l'arithmétique restent valables.


    Si c'est juste pour l'exercice, tu peux essayer de t'y coller. Si c'est pour travailler avec, utilise GMP.

  7. #7
    Membre actif
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juillet 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2007
    Messages : 193
    Points : 274
    Points
    274
    Par défaut
    si tu veux vraiment te baser sur du type char, tu peux.
    Quelque chose me dit que tu es étudiant d'epita ou d'epitech, que tu dois faire le projet bistromatique. Vu la date, j'obterais plus pour Epitech vu que ca doit etre la fin de la "piscine" en ce moment.

    Pour faire des operations sur des nombres infiniment long, en se basant sur des chaines de caractères, il faut que tu fonctionne par retenu.

    pour te donner des exemples:
    une addition de "1234" et "1234" :
    - 4+4 = 8
    - 3+3 = 6
    - 2+2 = 4
    - 1+1 = 2
    -> 2468

    Ici c'est un cas classique, ou tu prend chaque chiffre et que tu les additionnes.
    Maintenant, si tu remplace "1234" par "1236":
    6+6 = 12, ici comme quand tu étais petit, tu peux avoir une retenu à ajouter à la dizaine au dessus ...

    Après tu dois bien penser a tous les cas de figure, si tu as une retenu sur ta dizaine la plus haute, que ce que tu fais (reallouer une autre chaine un poil plus grande ? ou encore une solution un peu plus optimisé).

    Pour les autres operations, je te laisse faire des recherches, sachant que si tu ne recherche pas forcément les performances, une multiplication de chiffre entier n'est rien d'autre qu'une succession d'addition ...

    Bon courage

  8. #8
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par 10_GOTO_10 Voir le message
    [edit]Grillé par un modérateur qui poste plus vite que son ombre[/edit]
    Plutôt par un modérateur qui n'a pas pris la peine de mettre un lien dans son message :lol

    Citation Envoyé par Obsidian
    En fait, calculer avec des « char » n'est pas la méthode la plus efficace. Le mieux reste encore d'utiliser les types natifs de ta machine (int) et de faire de l'arithmétique avec, comme sur papier. Ce n'est pas forcément très difficile en soi, mais cela demande d'être TRÈS soigneux, et c'est quand même beaucoup de boulot, car il faut ré-implémenter toutes les opérations arithmétiques de base et gérer l'allocation de la mémoire avec.
    En fait, le calcul en binaire est certes plus efficace, et pas plus difficile à implémenter que la méthode avec des chaînes, mais c'est l'affichage du résultat qui est très compliquée.

  9. #9
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 950
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 950
    Points : 5 668
    Points
    5 668
    Par défaut
    Hoa,
    Citation Envoyé par Melem Voir le message
    En fait, le calcul en binaire est certes plus efficace, et pas plus difficile à implémenter que la méthode avec des chaînes, mais c'est l'affichage du résultat qui est très compliquée.
    Pas du tout, on fait exactement comme pour tout affichage : on extrait les modulos 10 (pour afficher en décimal) successifs.
    Si l'implémentation est bien faite, ça va bien assez vite pour qu'on n'ait pas le temps de voir le temps de calcul de la chaîne (à moins d'avoir un vraiment très grand nombre ).

    Et, à moins de vouloir passer du temps à faire une implémentation, il vaut mieux utiliser une bibliothèque disponible (GMP, par exemple).
    Car le principe est très simple, mais pour être suffisamment complet, c'est relativement long à écrire/tester.

  10. #10
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par droggo Voir le message
    Pas du tout, on fait exactement comme pour tout affichage : on extrait les modulos 10 (pour afficher en décimal) successifs.(
    Ou les modulos (int)(10^((int)log10(UINT_MAX))) successifs . Bon, le "très" était en effet peut-être une exagération. Mais en implémentation, c'est nettement plus compliqué de faire un seul appel à printf quand même, non ?

  11. #11
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 950
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 950
    Points : 5 668
    Points
    5 668
    Par défaut
    Hoa,

    Pourquoi aller chercher des log ?

    De toute manière, si on veut utiliser ces grands nombres, on n'échappe pas à l'implémentation des fonctions permettant de les convertir en chaîne d'une part, et permettant de les lire depuis une chaîne d'autre part.

    Ces fonctions sont d'ailleurs les 2 plus simples à écrire pour la bibliothèque, mais impliquent que les opérations basiques le soient déjà.

  12. #12
    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 Melem Voir le message
    En fait, le calcul en binaire est certes plus efficace, et pas plus difficile à implémenter que la méthode avec des chaînes, mais c'est l'affichage du résultat qui est très compliquée.
    Ce qu'on fait dans ce genre de bibliothèque, c'est utiliser une représentation en base B. B étant choisit de manière à être facilement stockable (donc B <= MAXUINT_MAX+1), B*B facilement manipulable (sinon les multiplications sont pénibles, donc B*B <= MAXUINT_MAX+1). B=10 est simple à visualiser mais pas très performant. Le plus grand B tel que B*B <= MAXUINT_MAX+1 est le plus performant pour les calculs (en temps et en espace) mais les conversions de et vers le décimal sont quand même relativement couteuses (pour donner une idée: le calcul de pi par F. Bellard a pris 103 jours, la conversion en décimal 13). La plus grande puissance de 10 tel que B*B <= MAXUINT+1, peut être le bon compromis dans certaines applications.

  13. #13
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 950
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 950
    Points : 5 668
    Points
    5 668
    Par défaut
    Joa,

    Pour être le plus performant possible, ce qu'on fait en fait dans ce genre de bibliothèque, est d'utiliser comme base le mot natif du processeur cible, en non signé.

    Pour gérer facilement les calculs, ça implique d'écrire les calculs de base (les algorithmes naïfs en assembleur, qui dispose de tous les mécanismes nécessaires.

  14. #14
    Membre actif Avatar de ABandApart
    Profil pro
    Étudiant
    Inscrit en
    Avril 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2010
    Messages : 90
    Points : 231
    Points
    231
    Par défaut
    Citation Envoyé par jerem721 Voir le message
    Bonjour à tous,

    je vous écrit car je recherche un méthode qui permet de faire des calcul avec des nombres infiniment grand.
    J'ai vu sur le net qu'on pouvais utilisé les char pour faire des calcule.
    Il y a t'il d'autre méthode? algorithme? qui permet de faire cela.

    merci d'avance.
    jerem721
    J'ai eu a le faire pour un projet d’école.
    J'ai utilisé des chaînes de caractères (char*), et j'ai posé les opérations comme en primaire.
    C'est la seule et unique façon d'y arriver.
    Finalement ça n'a pas été aussi dur que ça, le plus dur étant d’évaluer l'expression, de gérer les priorités (parenthèses, priorités de signe), etc...

    Bonne chance.

  15. #15
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    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 401
    Points : 23 780
    Points
    23 780
    Par défaut
    Citation Envoyé par Dareho Voir le message
    J'ai utilisé des chaînes de caractères (char*), et j'ai posé les opérations comme en primaire. C'est la seule et unique façon d'y arriver.
    On a expliqué au-dessus quelle est l'approche la plus sensée. Utiliser des chaînes de caractères est un raccourci fréquent parce qu'on ne fait pas l'association entre la façon dont le binaire est manipulé par le micro-processeur et la façon dont on calcule soi-même. Il est important de comprendre qu'au final, c'est le même procédé.

    Ramener cela à des chaînes de caractères est utile quand on souhaite directement compter en décimal et afficher le résultat facilement, comme on l'a dit au-dessus, mais c'est peu efficace en termes de mémoire et ce n'est pas évolutif du tout. Et dans tous les cas : ça ne peut certainement pas être un cas d'école à donner en exemple.

    Alors, s'y lancer pour un projet personnel, à la limite, mais annoncer que « c'est la seule et unique façon d'y arriver », ça me paraît très excessif.

  16. #16
    Membre actif Avatar de ABandApart
    Profil pro
    Étudiant
    Inscrit en
    Avril 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2010
    Messages : 90
    Points : 231
    Points
    231
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    On a expliqué au-dessus quelle est l'approche la plus sensée. Utiliser des chaînes de caractères est un raccourci fréquent parce qu'on ne fait pas l'association entre la façon dont le binaire est manipulé par le micro-processeur et la façon dont on calcule soi-même. Il est important de comprendre qu'au final, c'est le même procédé.

    Ramener cela à des chaînes de caractères est utile quand on souhaite directement compter en décimal et afficher le résultat facilement, comme on l'a dit au-dessus, mais c'est peu efficace en termes de mémoire et ce n'est pas évolutif du tout. Et dans tous les cas : ça ne peut certainement pas être un cas d'école à donner en exemple.

    Alors, s'y lancer pour un projet personnel, à la limite, mais annoncer que « c'est la seule et unique façon d'y arriver », ça me paraît très excessif.
    La je dois bien avouer ne pas comprendre comment faire avec des types primitifs comme un int.

    A partir du moment ou ton nombre dépasse 2^32 (unsigned int), il devient impossible de le manipuler.

    ou alors "123456789123456789" devient

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int part[3];
     
    part[0] = 1234567;
    part[1] = 891234;
    part[2] = 56789;
    Et la ça devient vraiment délicat et complexe pour un gain de performance, complètement négligeable.

    Ou alors je n'ai pas compris ta manière de procéder, ce qui est sûrement l'explication la plus probable

  17. #17
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 950
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 950
    Points : 5 668
    Points
    5 668
    Par défaut
    Hia,
    Citation Envoyé par Dareho Voir le message
    A partir du moment ou ton nombre dépasse 2^32 (unsigned int), il devient impossible de le manipuler
    La limite n'est pas forcément 2^32, elle dépend du processeur.

    Pour manipuler aisément ces données de la taille des mots native du processeur, il faut utiliser l'assembleur. Les processeurs disposent de tout ce qu'il faut pour prévenir en cas de débordement (en clair : retenue à reporter), ce qui est le seul soucis pour l'application des algorithmes.

    Citation Envoyé par Dareho Voir le message
    ou alors "123456789123456789" devient

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int part[3];
     
    part[0] = 1234567;
    part[1] = 891234;
    part[2] = 56789;
    Non, il ne devient pas ça, car tu te contentes de découper la chaîne. Il faut la traduire en binaire, et voir combien de mots elle utilise, etc.

  18. #18
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    Ce qu'on fait dans ce genre de bibliothèque, c'est utiliser une représentation en base B. B étant choisit de manière à être facilement stockable (donc B <= MAXUINT_MAX+1), B*B facilement manipulable (sinon les multiplications sont pénibles, donc B*B <= MAXUINT_MAX+1). B=10 est simple à visualiser mais pas très performant. Le plus grand B tel que B*B <= MAXUINT_MAX+1 est le plus performant pour les calculs (en temps et en espace) mais les conversions de et vers le décimal sont quand même relativement couteuses (pour donner une idée: le calcul de pi par F. Bellard a pris 103 jours, la conversion en décimal 13). La plus grande puissance de 10 tel que B*B <= MAXUINT+1, peut être le bon compromis dans certaines applications.
    Cela me semble en effet être une bonne approche.

    Citation Envoyé par Dareho
    La je dois bien avouer ne pas comprendre comment faire avec des types primitifs comme un int.

    A partir du moment ou ton nombre dépasse 2^32 (unsigned int), il devient impossible de le manipuler.
    On traduit la chaîne qu'on va manipuler en binaire, par exemple "12" en 1100 (pas "1000"). On fait ses calculs sur ces binaires. Ces nombres binaires peuvent être représentés par des tableaux "d'octets", des tableaux de unsigned char donc par exemple. Pour l'affichage, chemin inverse : on convertit le tableau d'octets en chaîne décimale puis on affiche la chaîne (ou faire la conversion et l'affichage simultanément). C'est en résumé l'approche avancée dans les premières réponses de cette disussion mais Jean Marc nous en a présenté une autre visiblement meilleure, mais partant toujours du même principe, comme toutes les autres méthodes.

Discussions similaires

  1. Projet : calculette à nombre entiers infiniment GRAND
    Par nzaero dans le forum Débuter
    Réponses: 13
    Dernier message: 01/08/2008, 16h34
  2. Réponses: 5
    Dernier message: 10/02/2006, 10h02
  3. [Debutant(e)]Calcul du nombre de ligne sous eclipse
    Par skywalker3 dans le forum Eclipse Java
    Réponses: 5
    Dernier message: 10/12/2004, 08h53
  4. calcule du nombre de jours entre 2 dates
    Par nazimb dans le forum ASP
    Réponses: 4
    Dernier message: 28/09/2004, 15h22
  5. Comparaison de base et calculs du nombre d'éléments dans Bas
    Par BXDSPORT dans le forum Bases de données
    Réponses: 3
    Dernier message: 19/07/2004, 08h00

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