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

Ada Discussion :

Parties entière et décimale d'un float


Sujet :

Ada

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 130
    Points : 80
    Points
    80
    Par défaut Parties entière et décimale d'un float
    Bonjour,
    Je fait en ce moment un programme qui résoud les équations du second degré et qui affiche le résultat sous la forme de fration (ce qui est le plus difficile), je n'ai pas trouver de fonction prédéfini qui convertie en fraction un float alors j'ai fait une partie de programme qui fait les calculs de fraction cela fonctionne correctement. Là ou j'ai un problème c'est lors de la convertion float -> integer pour faire des fractions entières ^^ alors j'en suis arrivé à devoir chercher la partie entière et décimal d'un float afin de faire la mise sous fraction c'est la partie de code ci dessous qui pose un problème de précision et je ne sais pas trop pourquoi. Pouvez regarder où se trouve mon erreur. je suppose que c'est lorsque je fais "float'image(x1-float'truncation(x1));" mais pas moyen de comprendre. Si vous connaissez une fonctionne qui renvoie la partie décimale je suis prenneur et je vous remercie d'avoir lu mon post.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    voici l'execution du programme :
    -qui fonctionne :
    123.4561
    Partie entière : 123
    Partie décimale : 4561
     
    -qui ne fonctionne pas correctement
    1324.1321
    Partie entière : 1324
    Partie décimale : 13208

    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
     
    with Ada.Integer_Text_IO, Ada.Float_Text_IO, Ada.Text_IO;
    use Ada.Integer_Text_IO, Ada.Float_Text_IO, Ada.Text_IO;
     
    procedure test is
     
    	procedure suppr_exp(ch : in string; decimale : out integer);
     
    	procedure suppr_exp(ch : in string; decimale : out integer) is
    		indp, j, lg : integer :=1;
    		--indp correspond à l'index du point
    		--j est l'itérateur charger de la longueur finale 
    		--lg est un autre index
    		chsortie : string(1..100) := (others => ' '); --stock sous forme de chaine la partie déimale
    	begin
    		while ch(lg)/='E' loop --tant que je n'ai pas trouvé la caractère 'E' j'incrément
    			lg := lg + 1;
    		end loop;
     
    		lg := lg - 1; -- j'ai trouvé le 'E' mais je veux être sur la case précédente
    		while ch(lg) = '0' loop --tant que j'ai un '0' je décrémente cette partie est censé récupérer le nombre sans les zéros
    			lg := lg - 1;
    		end loop;
     
    		while ch(indp) /= '.' loop	--je cherche la position du point dans la chaine
    			indp := indp + 1;
    		end loop;
     
    		for i in 1 .. lg loop --sur la longueur de la chaine
    			if i /= indp then --si j'ai l'itérateur égale à l'indice du point je fait rien sinon j'écris dans une autre chaine le résulat
    				chsortie(j):=ch(i);
    				j := j + 1;
    			end if;
    		end loop;
     
    		decimale := integer'value(chsortie(1 ..j)); --et je convertie cette chaine en entier
    	end suppr_exp;
     
     
    	x1 : float;
    	ch : string(1..20) := (others => ' ');
    	long : integer;
    	dec : integer;
    begin
    	get(x1);
    	long := float'image(x1-float'truncation(x1))'last; --stock la longueur de la chaine
    	put("Partie entière : "); put(integer(float'truncation(x1)),1); --affiche la partie entière
    	new_line;
    	ch(1..long) := float'image(x1-float'truncation(x1)); --stock la différence du float et de la partie entière j'obtiens donc la partie décimale sous la forme exponentiel 
    	suppr_exp(ch, dec); --le traitement qui convertie le float en entier
    	put("Partie décimale : "); put(dec,1);	--et l'affiche
    end test;

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 130
    Points : 80
    Points
    80
    Par défaut
    finalement j'ai repris mon algo et je l'ai complétement refait et ca fonctionne merci quand même de vous être pencher sur mon problème si vous voulez ma solution n'hésiter à me demander ^^

  3. #3
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    En fait tu aurais toujours pu utiliser la fonction modf du C via les interfaces.

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 130
    Points : 80
    Points
    80
    Par défaut
    j'ai regardé plusieurs site mais je ne comprends pas la méthode pour importer une fonction du C, comment fonctionne cette interfacage ?

  5. #5
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    Je pense que ceci devrait répondre largement à tes attentes :

    http://www.ghs.com/download/whitepapers/ada_c++.pdf

    Si tu as un problème avec les interfaces dis-le, ça n'est vraiment pas compliqué.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 130
    Points : 80
    Points
    80
    Par défaut
    merci pour ce PDF, donc j'essaie de faire l'import de modf donc j'ai :
    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
     
    with text_io, ada.float_text_io, interfaces.c;
    use text_io, ada.float_text_io, interfaces.c
     
    procedure test is
         procedure cmodf (x : in c_float; iptr : out c_float);
         pragma import (C, cmodf, "math.h");
     
         ma_valeur : interfaces.c.c_float;
         mon_reste : interfaces.c.c_float;
    begin
         get(ma_valeur);
         get(mon_reste);
     
         cmodf(ma_valeur, mon_reste);
         put(c_flaot'image(mon_reste));
    end test;
    Ici j'ai un bug je demande un get sur un c_float mais le compilateur ne prend pas (normal vu les types) et je pense que c'est la meme chose pour le put, bref j'ai un problème de type et je ne sais pas si mon import est juste. est ce que vous pouvez vérifier e que j'ai fait.

  7. #7
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    c_flaot'image(mon_reste)
    Tu as inversé le o et le a ici.

    Donnes-nous le message d'erreur de ton compilateur.

  8. #8
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    De plus ton import est faux.

    Ce qu'il faut mettre, c'est :

    pragma import( C , "le nom de la fonction existante en C" )

    De mémoire il me semble que le troisième paramètre n'est pas nécessaire (et même il me semble que c'est la source de problème d'édition des liens sous OSX)

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 130
    Points : 80
    Points
    80
    Par défaut
    bon donc je ne comprends pas un peu tout et je ne trouve pas d'exemple simple et même en faisant :
    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
    with text_io, Ada.Float_Text_IO, interfaces.c;
    use text_io, Ada.Float_Text_IO, interfaces.c;
     
    procedure test is
         procedure cmodf (x : in interfaces.c.c_float; iptr : out interfaces.c.c_float);
         pragma import (C, modf);
     
         ma_valeur : c_float;
         mon_reste : c_float;
    begin
         get(ma_valeur);
         get(mon_reste);
     
         cmodf(ma_valeur, mon_reste);
         put(c_float'image(mon_reste));
    end test;
    ca ne marche pas de plus je ne comprends pas comment se passe l'association de la procedure ada a la fonction c

  10. #10
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    Citation Envoyé par PRomu@ld Voir le message
    Donnes-nous le message d'erreur de ton compilateur.

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 130
    Points : 80
    Points
    80
    Par défaut
    oups oui voila le message d'erreur :

    GNAT GPL 2008 (20080521)
    Copyright 1992-2008, Free Software Foundation, Inc.

    Compiling: test.adb (source file time stamp: 2008-07-31 07:40:00)

    1. with text_io, Ada.Float_Text_IO, interfaces.c;
    |
    >>> warning: no entities of "float_text_io" are referenced

    5. procedure cmodf (x : in interfaces.c.c_float; iptr : out interfaces.c.c_float);
    |
    >>> missing body for "cmodf"

    6. pragma import (C, modf);
    |
    >>> "modf" is undefined
    >>> possible misspelling of "Mode"

    11. get(ma_valeur);
    1 6
    >>> no candidate interpretations match the actuals:
    >>> missing argument for parameter "Item" in call to "get" declared at a-tiflio.ads:76, instance at a-flteio.ads:20
    >>> missing argument for parameter "Item" in call to "get" declared at a-tiflio.ads:54, instance at a-flteio.ads:20
    >>> missing argument for parameter "Item" in call to "get" declared at a-textio.ads:242
    >>> missing argument for parameter "Item" in call to "get" declared at a-textio.ads:208
    >>> expected type "Standard.Float"
    >>> found type "Interfaces.C.C_float"
    >>> ==> in call to "Get" at a-tiflio.ads:59, instance at a-flteio.ads:20
    >>> ==> in call to "Get" at a-textio.ads:243
    >>> ==> in call to "Get" at a-textio.ads:209

    12. get(mon_reste);
    1 6
    >>> no candidate interpretations match the actuals:
    >>> missing argument for parameter "Item" in call to "get" declared at a-tiflio.ads:76, instance at a-flteio.ads:20
    >>> missing argument for parameter "Item" in call to "get" declared at a-tiflio.ads:54, instance at a-flteio.ads:20
    >>> missing argument for parameter "Item" in call to "get" declared at a-textio.ads:242
    >>> missing argument for parameter "Item" in call to "get" declared at a-textio.ads:208
    >>> expected type "Standard.Float"
    >>> found type "Interfaces.C.C_float"
    >>> ==> in call to "Get" at a-tiflio.ads:59, instance at a-flteio.ads:20
    >>> ==> in call to "Get" at a-textio.ads:243
    >>> ==> in call to "Get" at a-textio.ads:209

  12. #12
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    Ok, je réinstalle gnat sur ma machine et je teste ce que ça donne.

  13. #13
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    Ceci fonctionne sur ma machine :

    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
    with Ada.Text_Io , Ada.Float_Text_Io , Interfaces.C  ;
    use Ada.Text_Io , Ada.Float_Text_Io , Interfaces.C ;
     
    Procedure Test is
     
       function Cmodf( X : in Double ; Y : access Double ) return Double ;
       pragma Import( C , CModf , "modf" );
     
       X , Frac : Double ;
       Y : aliased Double ;
     
    begin
     
       X := 5.33 ;
     
       Frac := Cmodf( X , Y'Access );
     
       Put( "partie fractionnelle : ");
       Put( Float(Frac) );
       New_Line ;
       Put( "partie entiere : " );
       Put( Float(Y) );
     
    end;
    En fait, je t'ai induit en erreur. D'une part, il faut bien utiliser les trois arguments pour le pragma import. Leur sens est le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pragma import( langage source , nom_local , "non de la fonction dans le langage source" );
    Il y a éventuellement d'autres paramètres, mais c'est pas très important pour l'utilisation que tu en as.

    Concernant les types il faut absolument les respecter (si la fonction en C demande des doubles, il faut lui donner des doubles), sinon tu auras dans le meilleur des cas une valeur erronée, dans le pire des cas, un segfault.

    Concernant les get/put, comme tu peux le voir, j'ai mis des cast, c'est pas forcément très propre mais ça à le mérite de fonctionner.

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 130
    Points : 80
    Points
    80
    Par défaut
    D'accord je comprends mieux comment utiliser l'import mais j'ai encore 1 question : Est ce qu'il existe un moyen de faire une saisi utilisateur des valeurs j'ai essayé le get(double(x)) et ça ne fonctionne pas, j'ai donc pensé à utiliser le scanf, le problème est que ce n'est pas une fonction très simple à importer et je n'ai pas trouvé le prototype complet de la fonction.

  15. #15
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    Le problème du scanf, c'est de pouvoir utiliser les paramètres variadics ce qui n'est pas simple : pas de variadic en ada donc ça veut dire passer par l'adresse du dernier élement et encore, j'ai des doutes pour que ça soit du code portable. A éviter donc.

    La solution que je propose, il y en a d'autres, c'est de lire un float classique puis de le caster lors de l'appel de la fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    X : Float ;
    ...
    Get(X);
    ...
    Fp := cmodf( double(X) , Ip'access );
    ...

  16. #16
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 130
    Points : 80
    Points
    80
    Par défaut
    D'accord merci beaucoup pour votre aide

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 13/01/2012, 13h03
  2. Comment extraire la partie entière ou décimale
    Par al9000 dans le forum Débuter
    Réponses: 2
    Dernier message: 31/01/2010, 20h04
  3. Garder la partie entière d'un float ??
    Par tintin72 dans le forum C++
    Réponses: 2
    Dernier message: 09/11/2005, 11h03
  4. partie décimale / partie entière
    Par NoBru dans le forum Access
    Réponses: 3
    Dernier message: 21/10/2005, 12h00
  5. UDF-Interbase qui renvoie la partie entière d'un décimal
    Par mondelphi dans le forum InterBase
    Réponses: 2
    Dernier message: 20/06/2005, 16h46

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