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

Langage C++ Discussion :

Ecriture scientifique en C++ (sans sprintf)


Sujet :

Langage C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 38
    Points : 31
    Points
    31
    Par défaut Ecriture scientifique en C++ (sans sprintf)
    Bonjour,

    Je suis sûr que le problème a été tourné dans tous les sens, mais je n'arrive pas à mettre la main sur la solution.

    Je suis en train d'écrire une bibliothèque d'affichage de graphiques scientifiques au format SVG, et je suis confronté à un tout petit souci.

    Je voudrais que lorsque mes graduations atteignent 10^6 (ou inversement 10^-6), elles soient écrites en écriture scientifique avec 3 chiffres significatifs. Mais seulement quand c'est nécessaire. Par exemple avoir des graduations comme suit :

    200000 -- 400000 -- 600000 -- 800000 -- 1e6 -- 1.2e6

    et non pas comme suit :

    0.2e6 -- 0.4e6 -- 0.6e6 -- 0.8e6 -- 1.0e6 -- 1.2e6

    Je sais que c'est possible en utilisant sprintf de librairies C, mais j'ai une cliente très pointilleuse, et elle ne veut pas de cette fonction.

    Merci pour votre aide.

  2. #2
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par skeleton18 Voir le message
    Bonjour,

    Je suis sûr que le problème a été tourné dans tous les sens, mais je n'arrive pas à mettre la main sur la solution.

    Je suis en train d'écrire une bibliothèque d'affichage de graphiques scientifiques au format SVG, et je suis confronté à un tout petit souci.

    Je voudrais que lorsque mes graduations atteignent 10^6 (ou inversement 10^-6), elles soient écrites en écriture scientifique avec 3 chiffres significatifs. Mais seulement quand c'est nécessaire. Par exemple avoir des graduations comme suit :

    200000 -- 400000 -- 600000 -- 800000 -- 1e6 -- 1.2e6

    et non pas comme suit :

    0.2e6 -- 0.4e6 -- 0.6e6 -- 0.8e6 -- 1.0e6 -- 1.2e6

    Je sais que c'est possible en utilisant sprintf de librairies C, mais j'ai une cliente très pointilleuse, et elle ne veut pas de cette fonction.

    Merci pour votre aide.
    streamobj << std::fixed << nombre;
    streamobj << std::scientific << nombre;

    Si je ne m'abuse (streamobj étant un objet stream; donc possiblement un std::stringstream).

    Si tu as besoin de te limiter à un certain nombre de caractère, ou à un certain exposant, j'utiliserais la comparaison (abs(log10(nombre)) < X) pour ce faire (plutôt que laisser le stream décider, selon la longeur de la valeur lorsqu'elle est transformée en chaine).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <sstream>
    #include <cmath>
    #include <iomanip>
     
    std::string get_scale_string(double n, unsigned int max_exp)
    {
      std::stringstream output;
     
      output << std::setprecision(0) << (std::abs(std::log10(n)) < max_exp ? std::fixed : std::scientific) << n;
      return output.str();
    }
    Est-ce que ça conviendrais à la cliente ? (et d'ailleurs, c'est quoi la raison pour ne pas vouloir utiliser sprintf ?)

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Points : 407
    Points
    407
    Par défaut
    Salut,

    Le plus simple serait d'écriture toi même cette fonction, ce n'est pas très compliqué.

    Soit tu l'affiche directement, soit tu fais une fonction qui retourne un char * selon ton besoin.

    Sinon, en utilisant du C++ et non des fonctions C, si c'est ça le problème de ta client, utilise std::cout, c'est possible de préciser le nombre de chiffres à afficher après la virgule ainsi que d'afficher le nombre en écriture scientifique.


    Edit : J'ai été devancé mais en effet utiliser la std me semble être la meilleure idée (si ta client le veut bien).

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 38
    Points : 31
    Points
    31
    Par défaut
    Ma client ne veut pas de "codage à la C" dans sa bibliothèque, mais cherchez pas à comprendre, vous n'y arriverez pas ^^
    Ca fait 6 mois que j'essaye :p

    Bon ben je m'en vais tester cette solution alors et je vous tiens au jus.
    Merci les gens.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 38
    Points : 31
    Points
    31
    Par défaut
    Re-salut les gens!

    Bon j'ai testé ta solution et ça marche pour les nombres strictement positifs.
    Du coup pour que ça marche dans tous les cas, j'ai fait un truc que je suppose très très moche. Du coup, je voulais avoir votre opinion

    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
    std::string notationScientifique(double dNombre, unsigned int iMaxExp)
    {
    	std::ostringstream ossNotationScientifique;
    	std::string sNotationScientifique;
     
    	if(std::abs(dNombre) != 0)
    	{
    		ossNotationScientifique << std::setprecision(0) << (std::abs(std::log10(std::abs(dNombre))) < iMaxExp ? std::fixed
    				: std::scientific) << std::abs(dNombre);
     
    	}
     
    	if (dNombre < 0) {
    		sNotationScientifique = "-" + ossNotationScientifique.str();
    	}
    	else if(dNombre > 0) {
    		sNotationScientifique = ossNotationScientifique.str();
    	}
    	else {
    		sNotationScientifique = "0";
    	}
     
    	return sNotationScientifique;
    }
    En tout cas merci pour votre aide

  6. #6
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Et ça, alors ?

    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 <iomanip>
    #include <sstream>
     
    #include <cmath>
     
     
    std::string notationScientifique(double dNombre, unsigned int iMaxExp)
    {
        if (dNombre == 0)
            return "0";
     
        std::stringstream output;
        output << std::setprecision(0) << (std::abs(std::log10( std::abs(dNombre) )) < iMaxExp ? std::fixed : std::scientific) << dNombre;
        return output.str();
    }

  7. #7
    Membre émérite Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 047
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 047
    Points : 2 251
    Points
    2 251
    Par défaut
    Un peu illisible quand même.
    Tout mettre sur une ligne n'en fait un code plus performant

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 38
    Points : 31
    Points
    31
    Par défaut
    @Astraya
    Oui c'est vrai. Je l'ai mis sur plusieurs lignes maintenant, plus facile à lire

    @Steph_ng8
    J'étais persuadé de l'avoir essayé ce matin, mais apparemment pas, vu que ça marche, enfin presque... C'est presque parfait :p
    Au lieu de m'afficher, mes valeurs comme :

    -2.0 -- -1.2 -- -0.4 -- 0.4 -- 1.2 -- 2.0

    Il m'affiche :

    -2 -- -1 -- -0 -- 0 -- 1 -- 2

    Du coup j'ai essayé de faire comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ossNotationScientifique << std::setprecision(0);
    	if (std::abs(std::log10(std::abs(dNombre))) >= iMaxExp) {
    		ossNotationScientifique << std::scientific;
    	}
    	ossNotationScientifique	<< dNombre;
    Mais ça, ça me donne :

    -2 -- -1 -- -0.4 -- 0.4 -- 1 -- 2

  9. #9
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par skeleton18 Voir le message
    @Astraya
    Oui c'est vrai. Je l'ai mis sur plusieurs lignes maintenant, plus facile à lire

    @Steph_ng8
    J'étais persuadé de l'avoir essayé ce matin, mais apparemment pas, vu que ça marche, enfin presque... C'est presque parfait :p
    Au lieu de m'afficher, mes valeurs comme :

    -2.0 -- -1.2 -- -0.4 -- 0.4 -- 1.2 -- 2.0

    Il m'affiche :

    -2 -- -1 -- -0 -- 0 -- 1 -- 2

    Du coup j'ai essayé de faire comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ossNotationScientifique << std::setprecision(0);
    	if (std::abs(std::log10(std::abs(dNombre))) >= iMaxExp) {
    		ossNotationScientifique << std::scientific;
    	}
    	ossNotationScientifique	<< dNombre;
    Mais ça, ça me donne :

    -2 -- -1 -- -0.4 -- 0.4 -- 1 -- 2
    Le std::setprecision(K) contrôle le nombre de chiffres après la virgule. Moi, je n'ai fait que donner un bout de code, à toi de le bidouiller aux petits oignons

Discussions similaires

  1. Export de fichier en ascii : ecriture scientifique
    Par Baelros dans le forum MATLAB
    Réponses: 1
    Dernier message: 07/03/2008, 19h45
  2. Ecriture sur une feuille sans enchevetrement
    Par geeksideofme dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 05/06/2007, 11h33
  3. Ecriture dans un fichier sans ecraser le contenu
    Par Mo_Poly dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 07/03/2007, 23h49
  4. [XSL] Gestion exposants / Ecriture scientifique
    Par VolaiL dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 28/03/2006, 11h27
  5. [MFC] Ecriture scientifique
    Par Kevgeii dans le forum MFC
    Réponses: 2
    Dernier message: 29/05/2005, 21h58

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