Fraction continue

pgl10 Messages postés 381 Date d'inscription samedi 18 décembre 2004 Statut Non membre Dernière intervention 25 avril 2024 - 11 févr. 2023 à 07:51
pgl10 Messages postés 381 Date d'inscription samedi 18 décembre 2004 Statut Non membre Dernière intervention 25 avril 2024 - 12 févr. 2023 à 09:51

A l'adresse : https://codes-sources.commentcamarche.net/source/104117-fraction-continue-generalisee il y a un code source qui effectue le calcul et l'affichage des fractions réduites obtenues avec une fraction continue généralisée définie par l'utilisateur. Il est possible aussi de calculer et afficher la fraction continue simple qui correspond à un nombre décimal donné ayant autant de chiffres que l'on veut.

Voici le code source pour ce programme nommé fractionner.

#include <iostream>
#include <cstddef>
#include <string>
#include "gmp.h"
#pragma comment(lib, "gmp.lib") 

// Pour convertir une string en int
int str2int(std::string str) {
    int n = 0;
    for(unsigned int i=0; i < str.size(); i++) {
        n = n*10 + (int(str[i]) - int('0'));
    }
    return n;
}

// Pour valider un nombre décimal positif
bool vdecim(std::string str) {
    std::size_t first = str.find_first_of(".");
    std::size_t last = str.find_last_of(".");
    if(first != last) return false;
    if(first != std::string::npos) str.erase(first, 1);
    for(unsigned int i=0; i < str.size(); i++) 
        if(str[i] < int('0') || str[i] > int('9')) return false;
    if(str[0] == int('0') && first != 1) return false;
    std::size_t found = str.find_first_not_of("0");
    if(found == std::string::npos) return false;
    return true;
}

// Pour valider un nombre entier positif
bool venti(std::string str) {
    for(unsigned int i=0; i < str.size(); i++) 
        if(str[i] < int('0') || str[i] > int('9')) return false;
    if(str[0] == int('0')) return false;
    return true;
}

// On lit dans la ligne de commande un nombre décimal positif x 
// et le nombre m maximum d'éléments a[i] souhaités.
// Exemple : fractionner.exe 3.1415926535897932384626433832795 15
// On calcule les m premiers éléments de la fraction continue simple 
// telle que : x = a[0]+(1/(a[1]+(1/(a[2]+(1/a[3]+ ... )))))
int main(int argc, char** argv) {
    if(argc < 3 ) {
        std::cout << "Il faut faire : fractionner x m" << std::endl;
        return 0;
    }
    std::string sx = std::string(argv[1]);
    std::cout << "x = " << sx << std::endl;
    if(!vdecim(sx)) {std::cout << "Erreur pour ce nombre d\202cimal" << std::endl; return 0;}
    std::string sm = std::string(argv[2]);
    std::cout << "m = " << sm << std::endl;
    if(!venti(sm)) {std::cout << "Erreur pour ce nombre entier" << std::endl; return 0;}
    mpq_t xn;
    mpq_init(xn);
    mpq_t xd;
    mpq_init(xd);
    mpq_t x;
    mpq_init(x);
    std::size_t found = sx.find(".");
    // Si x est un nombre entier
    if(found == std::string::npos) mpq_set_str(x, sx.c_str(), 10);
    else {
        std::string sn = sx;
        sn.erase(found, 1);
        mpq_set_str(xn, sn.c_str(), 10);
        std::string sd = "1";
        for(unsigned int i=0; i < sx.size()-found-1; i++) sd = sd + "0";
        mpq_set_str(xd, sd.c_str(), 10);
        // Pour : x = n/d
        mpq_div(x, xn, xd);
    }
    mpz_t zi;
    mpz_init(zi);
    // zi (puis xi) est la partie entière de x
    mpz_set_q(zi, x);
    mpq_t xi;
    mpq_init(xi);
    mpq_set_z(xi, zi);
    gmp_printf("%Qd ", xi);
    int m = str2int(sm);
    int n = 1;
    while(n < m) {
        // Si x-xi = 0 : c'est terminé.
        mpq_sub(xi, x, xi);
        if(mpq_cmp_ui(xi, 0, 1) == 0) break;
        mpq_inv(x, xi);
        mpz_set_q(zi, x);
        mpq_set_z(xi, zi);
        gmp_printf("%Qd ", xi);
        n = n+1;
    };
    std::cout << std::endl;
    return 0;
}

Voici un exemple de fichier essais.bat pour l'utiliser.

@echo off
echo.
fractionner.exe  123  15 
echo.
fractionner.exe  3.14  15 
echo.
fractionner.exe 3.1415926535897932384626433832795 15
echo.
pause

Et voici l'affichage obtenu sur la console Windows.

x = 123
m = 15
123 

x = 3.14
m = 15
3 7 7 

x = 3.1415926535897932384626433832795
m = 15
3 7 15 1 292 1 1 1 2 1 3 1 14 2 1 

9 réponses

Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 656
11 févr. 2023 à 15:15

bonjour plg, c'est pas sur le forum qu'il faudrait expliquer comment fonctionne ton source, mais dans sa description.


0
pgl10 Messages postés 381 Date d'inscription samedi 18 décembre 2004 Statut Non membre Dernière intervention 25 avril 2024 11
11 févr. 2023 à 15:52

Bonjour Whismeril,

Mon code source : "Fraction continue généralisée" est publié avec sa propre description tout à fait explicite et suffisante. Par contre, j'ai mis dans le forum ce petit complément pour les visiteurs qui souhaitent calculer et afficher la fraction continue simple qui correspond à un nombre décimal sans avoir à écrire un programme pour cela. Et de plus, ils ont aussi la possibilité de déposer un commentaire ou une question.

Je te propose de bien regarder ce que tu as commenté beaucoup trop vite. Et je ne sais pas qui s'appelle plg !

Quand CCM-CS permettra de commenter un envoi en CodeS Sources ce sera différent ! Mais en attendant ...

Salutations.


0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 656
11 févr. 2023 à 16:47

Ok, mes doigts ont fourché pgl et non plg.

Mais ça ne change rien au fait que ça aurait dû être dans la description du source, pas sur le forum ni même en commentaire si un jour les commentaires reviennent.


0
pgl10 Messages postés 381 Date d'inscription samedi 18 décembre 2004 Statut Non membre Dernière intervention 25 avril 2024 11
11 févr. 2023 à 17:26

Whismeril,

Je ne comprend rien à ton commentaire.

Je répète que mon code source "Fraction continue généralisée" comporte sa propre description dont il n'est pas question ici. Cette description est en bonne place avec le code source. Il me semble particulièrement évident que mon message dans le forum concerne autre chose. Il suffit de lire ce qui est écrit.

Et je suis certain que quelques visiteurs sont maintenant très contents de pouvoir calculer et afficher facilement la fraction continue simple qui correspond à un nombre décimal. Ce qui est complètement différent de mon code source. C'est même la démarche inverse !

Et quand les commentaires du code source reviendront, on pourra les utiliser. Actuellement ce n'est pas le cas.

Il est dommage d'avoir à préciser ce qui est évident. Salutations.


0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 656
11 févr. 2023 à 18:34

Dans ce que tu as écrit il n.est nullement évident qu'il ne s'agit pas de la façon d'utiliser ton code.

 il y a un code source qui effectue le calcul et l'affichage des fractions réduites obtenues avec une fraction continue généralisée définie par l'utilisateur. Il est possible aussi de calculer et afficher la fraction continue simple qui correspond à un nombre décimal donné ayant autant de chiffres que l'on veut.

Quand je lis, relis ceci, je comprends que ton source fait les 2.


Mais du coup, s'il s'agit d'un autre source, il n'a pas non plus sa place dans le forum.

Il faut le poster dans les sources.


0
pgl10 Messages postés 381 Date d'inscription samedi 18 décembre 2004 Statut Non membre Dernière intervention 25 avril 2024 11
11 févr. 2023 à 19:03

Whismeril,

Cette fois-ci je suis d'accord avec ton commentaire précédent : j'aurais pu poster ce petit code source complémentaire dans les Codes Sources. Je ne l'ai pas fait pour deux raisons : 1°) c'est un très petit code source qui n'en a pas besoin et 2°) un visiteur peut poster un commentaire dans le forum mais ce n'est pas possible actuellement dans les CodeS SourceS.

J'espère bien qu'après tous les échanges précédents on peut savoir ou apprendre ce que sont les trois entités différentes : une fraction continue simple, une fraction continue généralisée et une fraction réduite.

Salutations.


0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
11 févr. 2023 à 20:28

Bonjour !

Il y a deux solutions pour résoudre ce souci:

  * Soit on met deux dossiers dans le code-sources contenant chacune des variantes, avec un readme explicatif à la racine.

  * Soit on met cette variante en commentaire du code. Les commentaires sur le code sont là pour discuter et approfondir une source. Donc ça me parait tout indiqué, si le code est vraiment tout petit.

Or, le problème actuel, c'est qu'on ne peut plus commenter les sources. Donc, contourner ce problème en liant un message dans le forum avec sa source, ce n'est certes pas idéal, mais je ne vois pas comment faire autrement. On pourra toujours migrer ces précisions quand les commentaires de sources reviendront.

0
pgl10 Messages postés 381 Date d'inscription samedi 18 décembre 2004 Statut Non membre Dernière intervention 25 avril 2024 11
12 févr. 2023 à 08:35

Bonjour cptpingu, bonjour tous,
      
Merci beaucoup pour ce message. Je ne peux pas utiliser la première solution, celle d'un petit dossier joint à l'intérieur du zip de l'envoi principal, parce que je ne peux pas actuellement modifier ce fichier zip. Si c'était possible, ce serait la solution idéale. Et je ne peux pas non plus utiliser la deuxième solution, celle d'un tout petit code complémentaire dans les commentaires de l'envoi principal, parce que actuellement les commentaires d'un envoi à CodeS SourceS sont impossibles.
       
J'ai donc cherché du mieux possible à contourner les bugs actuels de CCM-CS avec un message dans le forum qui explique clairement ma démarche non seulement avec le petit source complémentaire mais aussi avec un fichier batch pour l'utiliser et un autre fichier qui montre l'affichage de la console Windows : tout cela présenté avec des titres très explicites.
      
J'en profite pour expliquer ici un résultat normal de ce petit programme qui calcule et affiche la fraction continue simple qui correspond à un nombre décimal. Prenons l'exemple du nombre d'or : ce nombre est irrationnel, tous les éléments de sa fraction continue simple sont des 1 mais il a un nombre infini de chiffres significatifs. On est donc obligé d'écrire une approximation du nombre d'or avec un nombre fini de chiffres significatifs. Si je donne à lire 0.61 au programme fractionner.exe j'obtiens les éléments suivants : 1 1 1 1 1 3 2 2. C'est bien le résultat exact, il ne comporte pas uniquement des 1 parce que 0.61 est seulement une approximation et les éléments modifiés sont toujours les derniers. On peut s'en rendre compte en donnant à traiter une seconde approximation plus longue, dans ce cas on obtiendra des 1 plus nombreux.
      
Et le langage C++ avec la bibliothèque GMP est un très bon langage de programmation pour effectuer facilement les opérations arithmétiques exactes qui sont nécessaires, même avec de très grands nombres.
      
Très cordialement, pgl10
     


0
pgl10 Messages postés 381 Date d'inscription samedi 18 décembre 2004 Statut Non membre Dernière intervention 25 avril 2024 11
Modifié le 12 févr. 2023 à 10:07

Dans mon dernier message ci-dessus j'ai écrit 0.61 pour une courte approximation du nombre d'or.

Veuillez noter mon erreur. C'est la valeur 1.61 que j'aurais dû écrire.

En effet, on a bien en fraction continue simple : 1.61 = 1+1/(1+1/(1+1/(1+1/(1+1/(3+1/(2+1/2))))))

Merci, pgl10


0
Rejoignez-nous