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 :

String vers float


Sujet :

C

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2002
    Messages : 12
    Par défaut String vers float
    Bonjour,

    Je dois convertir une chaine de 4 car représentant les 4 bytes d'un float
    en float.

    Je cherche mais ne trouve pas

    Merci de vos conseils.

    Alfy

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1

  3. #3
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    Salut,

    Il y a des problèmes d'alignement et d'endianess qui font que tu ne peux pas caster directement pour considérer l'adresse de ta chaine comme celle d'un float. Dans l'exemple ci dessous, on écrase le float avec la chaine "\x00\x00\x00\x00". Le premier caractère '-' n'est là que pour sensibiliser au problème d'alignement résolu par le memcpy. L'endianess n'est pas résolu, mais comme on ne sait pas d'où sort ton char[4]...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <stdio.h>
    #include <string.h>
     
    int main(void)
    {
        char input[] = "-\x00\x00\x00\x00";
        float value = 1234.56;
        memcpy(&value, &(input[1]), 4);
        printf("%f\n", value);
        return 0;
    }
    Si tu es sûr de l'alignement et de l'endianness, tu peux faire directement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include <stdio.h>
     
    int main(void)
    {
        char input[] = "\x00\x00\x00\x00";
        printf("%f\n", (float)*input);
        return 0;
    }
    A+

    Pfeuh

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2002
    Messages : 12
    Par défaut
    Merci Pfeuh, je pense que c'est bien la solution
    Je cherchais une fonction, mais elle ne doit pas exister.

    Alfy

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Bonjour,

    Citation Envoyé par pfeuh Voir le message
    Il y a des problèmes d'alignement et d'endianess
    Euh, non : une chaine de caracteres ne presente pas de probleme d'alignement ou d'endianness. Et pour la conversion, il existe strtof qui fait exactement ce qui est demande.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Bousk Voir le message
    strtof
    Les 2 fonctions sont sur la même page de manuel



    Mais j'avoue ne pas avoir vu strtof() avant ton post

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2002
    Messages : 12
    Par défaut
    Le souci c'est que les 4 bytes du float sont contenus dans une chaine de 4 car.
    bit 0-22 = mantisse, 23-30 exposant, 31 signe

    Ce n'est pas la représentation du nombre en string mais son codage.

    Donc je ne pense pas que strtof soit approprié ou je me tropme

    Alfy

  9. #9
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    Citation Envoyé par gangsoleil Voir le message
    Euh, non : une chaine de caracteres ne presente pas de probleme d'alignement ou d'endianness. Et pour la conversion, il existe strtof qui fait exactement ce qui est demande.
    Je pense que tu n'as pas compris ce que veux le PO. il ne veut pas transformer la chaine "1234.56" en float 1234.56. Il veux transformer la chaine de 4 caractères qui contient en fait les 4 bytes d'un float32 en un float32. Par exemple la chaine "\000\000\000\000" (ou encore [0, 0, 0, 0]) en 0.00. comme on ne sait pas d'où vient cette chaine et qu'elle peut être une partie d'une autre chaine, je persiste à dire qu'il peut y avoir un problème d'alignement. Et strtof ne fait pas ce que veux le PO

  10. #10
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Je crois qu'il faudrait que tu expliques un peu mieux ton problème et nous donne un exemple de chaine à convertir

    @pfeuh : la représentation d'un float32 est telle fixe ? Autant un entier c'est facile, autant un float....

  11. #11
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Citation Envoyé par pfeuh Voir le message
    Je pense que tu n'as pas compris ce que veux le PO.
    Effectivement, merci de l'explication.

    Citation Envoyé par alfy Voir le message
    Le souci c'est que les 4 bytes du float sont contenus dans une chaine de 4 car.
    bit 0-22 = mantisse, 23-30 exposant, 31 signe
    Est-ce que cette representation est fixe ?
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2002
    Messages : 12
    Par défaut
    Pour info, voilà mon problème

    Je recois une chaine (connexion à un onduleur photovoltaique) qui me donne ceci

    Byte 0 -état de la transmission
    Byte 1 -état de l'onduleur
    Byte 2 -V3
    Byte 3 -V2
    Byte 4 -V1
    Byte 5- V0
    Byte 6- CRC low
    Byte 7- CRC high

    Les 4 bytes V3..V0 représentent un nombre float
    pour retrouver sa valeur originale il est nécessaire de mettre en séquence les 4 bytes et de les lire comme un nombre float 32 bits (normes ANSI)
    (traduction libre de la doc)
    La notion de big ou little endian n'est pas indiquée, mais le test est vite fait dans la mesure ou je peux tester le résultat et le comparer à ce que la machine affiche sur son display.

    exemple
    recu 00 06 45 2d b6 32 9c 34
    donc - 45 2d b6 32 - qui doit donner un float de valeur 2779.387207

    Alfy

  13. #13
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    J'ai fait un code qui fait le taff :

    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
    int main (void)
    {
        printf("sizeof(float) = %d\n"
               "sizeof(int) = %d\n"
               "sizeof(long) = %d\n", sizeof(float), sizeof(int), sizeof(long) );
     
        char *chaine = "452db632";
     
        unsigned long hexa = strtoul(chaine, 0, 16);
        printf("hexa = %X\n", hexa);
     
        float *pt = (float*)&hexa;
        float nombre = *pt;
        printf("nombre = %f\n", nombre);
     
        return 0;
    }
    Mais j'ai de gros doutes sur la robustesse....

  14. #14
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2002
    Messages : 12
    Par défaut
    Ok c'est tout a fait cela

    Je me doutais que c'était un peu ambigü a expliquer comme problème

    Alfy

  15. #15
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Il faudra tester sur ta machine cible, le code se base sur le fait qu'un float et un long occupe le même nombre d'octets (4 sous Windows XP). Tu nous diras si ça marche bien.

  16. #16
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2002
    Messages : 12
    Par défaut
    Oui cela fonctionne, je suis sous Linux et c'est 4 aussi

    Merci bcp

    Alfy

  17. #17
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    Citation Envoyé par Bktero Voir le message
    la représentation d'un float32 est telle fixe
    En gros oui, il y a un standard, le IEEE je ne sais plus combien. Je dis en gros parce que qu'il y a toujours les histoires d'endianess. J'ai échangé des floats32 entre des cartes à 8031, à pic24, à pic32, à arm 32 et un PC sans aucun problème. En C, bien sûr, mais aussi en python pour le PC.

  18. #18
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par alfy Voir le message
    Oui cela fonctionne, je suis sous Linux et c'est 4 aussi

    Merci bcp

    Alfy
    C'est surtout sur une machine 64 bits que ça risque de partir en vrille. Si tu es restes sur du 32 bits, ça devrait aller. De rien pour le coup de main ^^

    Citation Envoyé par pfeuh Voir le message
    En gros oui, il y a un standard, le IEEE je ne sais plus combien. Je dis en gros parce que qu'il y a toujours les histoires d'endianess. J'ai échangé des floats32 entre des cartes à 8031, à pic24, à pic32, à arm 32 et un PC sans aucun problème. En C, bien sûr, mais aussi en python pour le PC.
    http://en.wikipedia.org/wiki/IEEE_754-1985
    Je présume que c'est celui-ci. Il y a effectivement la question de l'endianess, il se trouve que dans le cas du PO ça tombe dans le bon sens.

  19. #19
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2002
    Messages : 12
    Par défaut Encore un peu d'aide svp
    Je reviens vers vous pour ce problème

    J'ai donc une chaine représentant un float
    - char *chaine = "\x45\x2d\xb6\x32";
    et ai initialisé 4 bytes pour le float
    - float energie;

    Je veux a présent que l'adresse du float soit l'adresse de chaine
    mais tous mes essais sont restés vains

    Merci

    Alfy

  20. #20
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    C'est tout simplement impossible.

    Si tu déclares deux entiers de type int, il te parait évident qu'ils seront à deux emplacements différents dans la mémoire et que donc les adresses seront différentes ?

    Il n'est donc pas possible qu'un objet float et qu'un objet char* aient la même adresse. En revanche, tu peux créer un pointeur sur float et lui donner comme valeur l'adresse de la chaine :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int main(void)
    {
        char *chaine = "\x45\x2d\xb6\x32";
        float *p_energie = chaine;
     
        printf("'%s' a l'adresse %p\n", chaine, chaine);
        printf("'%f' a l'adresse %p\n", *p_energie, p_energie);
     
        return 0;
    }
    Rien ne te garantit par contre que l'interprétation des 4 octets de chaine via le pointeur p_energie donne un résultat probant.

Discussions similaires

  1. Conversion string vers float - résultat étrange
    Par polysil dans le forum Langage
    Réponses: 2
    Dernier message: 18/06/2013, 14h59
  2. du String Vers Float
    Par marocdivers dans le forum Interfaces Graphiques en Java
    Réponses: 1
    Dernier message: 26/05/2011, 07h47
  3. tentative conversion string vers float
    Par firemax dans le forum C
    Réponses: 10
    Dernier message: 21/08/2007, 17h42
  4. [C++] conversion classe string vers float
    Par agrosjea dans le forum C++
    Réponses: 5
    Dernier message: 14/03/2007, 13h45

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