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 :

Faire un for avec comme index un float ?


Sujet :

C

  1. #1
    Membre confirmé
    Profil pro
    ingénieur
    Inscrit en
    Septembre 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur

    Informations forums :
    Inscription : Septembre 2008
    Messages : 54
    Par défaut Faire un for avec comme index un float ?
    Bonjour

    je souhaiterais pouvoir faire une boucle avec comme index, un nombre commençant par 0.000 , comment s'y prendre pour que ce dernier soit pris en compte et me sort 0.001,0.002,0.003 etc... ?

    merci d'avance.

  2. #2
    Expert confirmé
    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 : 39
    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
    Par défaut
    Naïvement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    double x; /* Je ne vois aucune raison de preferer naturellement float a double */
    for(x = 0.000; x <= 1.000; x += 0.001)
       /* Le traitement */ ;
    Mais je préfère, et recommande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int i;
    double x;
    for(i = 0; i <= 1000; i++)
    {
        x = i / 1000.0;
        /* Le traitement */ ;
    }

  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,

    Citation Envoyé par Melem Voir le message
    Naïvement :Je ne vois aucune raison de preferer naturellement float a double
    Il en a une pourtant que j'invoque assez souvent: Faire tourner sur PC des sources C qui tournent à l'origine sur des petits processeurs genre 8051 ne connaissant que le float32, d'ailleurs largement suffisant pour ce qu'on leur demande.

    A+

    Pfeuh

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    153
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Avril 2009
    Messages : 153
    Par défaut
    Voire pour effectuer un traitement sans devoir passer par des variables temporaires.

    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    double r;
    double var = 0.25
    for (r = 0.000; r < (90 + var); r += var)
    {
        rotation (r); /* On effectue une rotation en degrés */
    }
    C'est pour moi plus efficace que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int cpt;
    double r = 0.000;
    double var = 0.25;
    for (cpt = 0; r < ((90 / var) + 1); cpt++)
    {
        r += var;
        rotation (r);
    }

  5. #5
    Expert confirmé
    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 : 39
    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
    Par défaut
    Citation Envoyé par pfeuh
    Il en a une pourtant que j'invoque assez souvent: Faire tourner sur PC des sources C qui tournent à l'origine sur des petits processeurs genre 8051 ne connaissant que le float32, d'ailleurs largement suffisant pour ce qu'on leur demande.
    Ah ?
    8051 specific language extensions are described below.

    Data sizes

    The compiler uses the following sizes for the various C data types:

    (...)
    float: 4 bytes (32 bits)
    double: 8 bytes (64 bits)
    (...)
    Source : http://www.crossware.com/datasheets/c8051nt.htm

    De toute façon j'ai pas dit que le type float ne servait à rien, que ça soit sur 8051 ou ailleurs, mais que s'il n'y a pas de raisons très particulières vaut mieux utiliser double plutôt que float.

    Bsans : franchement, utiliser un type flottant comme indice dans une boucle n'est pas une très bonne idée à cause de l'imprécision de ces types. Puis, je doute que le second code est plus efficace que le premier mais de toute façon, que ça soit vraiment le cas où pas, tes deux techniques ne sont pas une bonne façon de faire une rotation animée, toujours à cause de l'imprécision des réels. La bonne méthode est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int i;
    double delta_angle = 0.25;
    for(i = 0; i <= 360; i++)
    {
        set_angle(i * delta_angle)
    }

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    153
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Avril 2009
    Messages : 153
    Par défaut
    C'était juste une illustration du fait qu'on puisse avoir besoin d'autre chose qu'un "compteur classique" dans une boucle.

    Je ne dis pas que c'est bien ou pas, juste que c'est faisable et que ça peut servir dans certains cas.

  7. #7
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 967
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 967
    Par défaut
    Kei,
    Citation Envoyé par BSans Voir le message
    C'était juste une illustration du fait qu'on puisse avoir besoin d'autre chose qu'un "compteur classique" dans une boucle.

    Je ne dis pas que c'est bien ou pas, juste que c'est faisable et que ça peut servir dans certains cas.
    Oui, mais avec des types flottants, il FAUT éviter ça, en raison des erreurs qui s'accumulent très vite.

  8. #8
    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 Melem Voir le message
    Ah ?
    Je n'ai pas dit que ça n'existait pas. Je dis juste que même avec le compilo Keil à 3000 euros pour la famille 8051 que j'utilise, je ne vais pas faire bosser un 8 bits en float64.

  9. #9
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 480
    Par défaut
    Citation Envoyé par droggo Voir le message
    Oui, mais avec des types flottants, il FAUT éviter ça, en raison des erreurs qui s'accumulent très vite.
    Moi, je suis également partisan de l'utilisation de float avant les double. D'abord parce que c'est généralement tout l'un ou tout l'autre : soit l'exposant d'un float permet d'aller suffisamment loin avec une précision honorable, soit les imprécisions se cumulent de manière exponentielle, lors de multiplications successives par exemple, et dans ce cas, passer de float à double n'apporte pas grand chose de plus : le nombre d'opérations possible est simplement doublé et non pas élevé au carré.

    L'utilisation de double a un coût. Cela fait deux transactions de bus au lieu d'une sur les machines 32 bits, même si le coprocesseur gère nativement les formats 64 bits, et cela double virtuellement la mémoire consommée. Tant que l'on utilise quelques float ou double par ci, par là, ça n'a pas trop de conséquence, mais pour ceux qui ont l'habitude d'utiliser des réels partout, et dans les langages objets tels que le C++, par exemple, où les classes sont faites pour hériter des précédentes, ça peut grossir très vite.

    D'une manière générale, on devrait choisir un format ou un autre qu'à partir du moment où l'on est certain de connaître ses limites, spécialement avec les nombres à virgule flottante (c'est beaucoup plus facile avec les entiers), sinon, on est incapable de prévoir quand une erreur sera susceptible de se produire. Et comme, dans ce cas, elle se traduira par un calcul erroné plutôt que par une erreur d'exécution (exception, segfault…), ses implications peuvent devenir dramatiques.

  10. #10
    Expert confirmé
    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 : 39
    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
    Par défaut
    Obsidian : Considère la boucle suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int i;
    for(i = 0; i < 10; i++)
       printf("Bonjour.\n");
    Parce que i ne prend que des valeurs compises entre 0 et 10, tu me recommanderais d'utiliser le type char pour i plutôt que int ? D'accord j'ai pris un exemple d'un faible intérêt, mais l'idée est bien là : L'ergonomie au niveau du code, c'est aussi important. Il ne faut pas toujours être maniac de performance (mais j'admets bien que dans certains cas il faut l'être, en OpenGL par exemple je n'utilise QUE des float). En langage C, double est aux réels ce que int est aux entiers. C'est pourquoi je conseille de toujours utiliser double au lieu de float, sauf quand il y a de raisons sérieuses de préférer float.

  11. #11
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 480
    Par défaut
    Citation Envoyé par Melem Voir le message
    Parce que i ne prend que des valeurs compises entre 0 et 10, tu me recommanderais d'utiliser le type char pour i plutôt que int ? D'accord j'ai pris un exemple d'un faible intérêt, mais l'idée est bien là : L'ergonomie au niveau du code, c'est aussi important. Il ne faut pas toujours être maniac de performance.
    Non (et encore) mais il me viendrait encore moins à l'idée de recommander aux gens d'utiliser systématiquement des « signed long long » à la place de tous les int parce qu'ils sont plus grands. L'exemple est pourtant beaucoup plus comparable, à commencer par les largeurs des champs qui sont identiques sur les machines actuelles. On pourrait aussi arguer que 2 milliards (pour un entier signé), c'est beaucoup mais ce n'est pas astronomique et peut être atteint dans la vie courante.

    Or, justement, la manie d'utiliser double systématiquement ne se « justifie » que par cela. Il n'est ni plus ni moins ergonomique d'utiliser le mot-clé float plutôt que double dans un programme, surtout dans la mesure où les formats sont normalisés et fixes, ce qui évite bien des surprises.

  12. #12
    Membre confirmé
    Profil pro
    ingénieur
    Inscrit en
    Septembre 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur

    Informations forums :
    Inscription : Septembre 2008
    Messages : 54
    Par défaut
    Bonjour à tous,

    merci pour vos réponses, car cela m'a permis de régler mon problème.

    J'ai juste une question pour melem, n'ayant pas trop besoin de précision j'ai utilisé dans mon programme, la version "naive" de la boucle :

    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
    #include <stdio.h>
    #define G 9.81
    #define N 0.16
    
    int main(void)
    {
       double t; /* Temps en seconde */
            float m; /* Longueur en m */
    
        printf("\t  t(s)\t(1/2)gt^2(m)\n");
          printf("\t===========================\n");
    
        for (t=0.00; t<=N; t += 0.01)  {
          m = 0.5*G*t*t;
            printf("\t %.3f \t    %.3f\n", t , m);
       }
        return 0;
    }
    Par contre pour la 2ème méthode je ne vois pas comment utilisé la varible X ? peux tu me dire comment l'intégrer dans mon code ? merci.

  13. #13
    Expert confirmé
    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 : 39
    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
    Par défaut
    Citation Envoyé par Obsidian
    Non (et encore) mais il me viendrait encore moins à l'idée de recommander aux gens d'utiliser systématiquement des « signed long long » à la place de tous les int parce qu'ils sont plus grands. L'exemple est pourtant beaucoup plus comparable, à commencer par les largeurs des champs qui sont identiques sur les machines actuelles.
    Je ne recommande systématiquement (par défaut) ni long, ni long long (C99), mais int. Tout simplement parce que le type entier par défaut du C. L'expression 1 par exemple n'est ni un char, ni un unsigned long, ni un long long, mais un int. sizeof(1) vaut sizeof(int). Quand tu écris long long n = 1, ça ne marche pas (en version archi extrêmiste : ça ne compile pas) tout de suite ! Dans une telle expression, le 1, qui est un int, est tout d'abord converti en 1LL, qui est enfin bien un long long. Cette conversion se fait automatiquement, implicitement, pendant la compilation. Si le C ne supportait pas les conversions implicites, alors long long n = 1 ne passerait pas à la compilation, il fallait écrire long long n = 1LL. C'est pareil avec les flottants. 1.0 n'est ni un float, ni un long double, mais un double. 1.0f par contre est bien un float et 1.0L est un long double.

    sedawk :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #define _N_ 16
    ...
    int i;
    double t;
     
    for(i = 0; i <= _N_; i++)
    {
        t = i / 100.0;
        m = 0.5 * G* t * t;
        ...
    }
    ...

  14. #14
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    t = i / 100.0;
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  15. #15
    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 Melem Voir le message
    mais int. Tout simplement parce que le type entier par défaut du C. L'expression 1 par exemple n'est ni un char, ni un unsigned long, ni un long long, mais un int. sizeof(1) vaut sizeof(int).
    Tout à fait. C'est ma façon de penser aussi. Sauf qu'en dessous de 16 bits, le int est pénalisant, car formé de deux bytes. Pour le cas d'une boucle de 0 à 10, je prendrais comme index un unsigned char pour un processeur 8 bits. Mais comme je sens bien que pour la majorité d'entre vous il n'y a pas de vie possible en dessous de 32 bits, je sors.

  16. #16
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Enfin, sur une plate-forme 8 bits, je m'attendrais à avoir ceci:
    • char -> 8 bits
    • short -> 8 bits
    • int -> 8 bits
    • long -> 16 bits

    Ensuite, si on passe à une plate-forme 16 bits...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  17. #17
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Enfin, sur une plate-forme 8 bits, je m'attendrais à avoir ceci:
    • char -> 8 bits
    • short -> 8 bits
    • int -> 8 bits
    • long -> 16 bits
    Ce n'est pas possible (enfin si la plate-forme respecte la norme bien entendue) : http://c.developpez.com/faq/?page=ty...S_taille_types

  18. #18
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ah, j'avais oublié les tailles minimales :-(
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Réponses: 4
    Dernier message: 17/04/2014, 13h38
  2. Réponses: 6
    Dernier message: 09/03/2009, 17h10
  3. Formulaire avec comme action="index.php?confirm.php" POSSIBLE ?
    Par jiojioforever dans le forum Langage
    Réponses: 2
    Dernier message: 14/11/2006, 11h13
  4. faire un fetch avec le nom d une table comme parametre
    Par cbon1 dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 18/09/2006, 17h08
  5. faire plusieur declaration avec boucle for ?
    Par debutant-1 dans le forum C
    Réponses: 4
    Dernier message: 18/05/2006, 20h19

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