Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2872 connectés 

 


Dernière réponse
Sujet : [language C] je trouve pas mon erreur avec le switch
Musaran Il manquait effectivement un break.
glutPostRedisplay est sytématiquement appelée, autant la sortir du switch.
'D' est de type char. key est de type unsigned char. Les comparer est risqué... T'es fâché avec les comparaisons ?
 
Et puis ça fait pas de mal d'aligner les instructions semblables.

Code :
  1. #include <ctype.h>
  2. #include <float.h>
  3. const float tolerance= 64*FLT_EPSILON ;//*0.0000001192092896 (float de 4 octets)
  4. float c= 0.0 ;
  5. int fnear(float arg1, float arg2){
  6. float diff= arg1>arg2 ? arg1-arg2 : arg2-arg1 ;//différence absolue
  7. return diff<tolerance ;
  8. }
  9. void keyboard (char key, int x, int y){
  10. switch (toupper(key)){
  11. case 'D':nbr_degre+= 2.0; j=  0.0; k=  1.0; l= 0.0; break;//rotation Y
  12. case 'S':nbr_degre+= 2.0; j=  0.0; k= -1.0; l= 0.0; break;//rotation Y
  13. case 'E':nbr_degre+= 2.0; j= -1.0; k=  0.0; l= 0.0; break;//rotation X
  14. case 'X':nbr_degre+= 2.0; j=  1.0; k=  0.0; l= 0.0; break;//rotation X
  15. case 'O':c -= 0.5 ;                                 break;
  16. case 'I':c += 0.5 ;
  17.       if(fnear(c,10)){profondeur= 1; }
  18.  else if(fnear(c,20)){profondeur= 2; }
  19.  else if(fnear(c,30)){profondeur= 3; }
  20.  else if(fnear(c,40)){profondeur= 4; }
  21.  //if(c>10-tolerance && c<40+tolerance) profondeur= (int)c/10 ;
  22.                                                     break;//manquait, optionnel maintenant
  23. }
  24. glutPostRedisplay() ;
  25. }

Rassures-moi: il y a une raison pour que la ligne en commentaire ne fasse pas l'affaire ?


Votre réponse
Nom d'utilisateur    Pour poster, vous devez être inscrit sur ce forum .... si ce n'est pas le cas, cliquez ici !
Le ton de votre message                        
                       
Votre réponse


[b][i][u][strike][spoiler][fixed][cpp][url][email][img][*]   
 
   [quote]
 

Options

 
Vous avez perdu votre mot de passe ?


Vue Rapide de la discussion
Musaran Il manquait effectivement un break.
glutPostRedisplay est sytématiquement appelée, autant la sortir du switch.
'D' est de type char. key est de type unsigned char. Les comparer est risqué... T'es fâché avec les comparaisons ?
 
Et puis ça fait pas de mal d'aligner les instructions semblables.

Code :
  1. #include <ctype.h>
  2. #include <float.h>
  3. const float tolerance= 64*FLT_EPSILON ;//*0.0000001192092896 (float de 4 octets)
  4. float c= 0.0 ;
  5. int fnear(float arg1, float arg2){
  6. float diff= arg1>arg2 ? arg1-arg2 : arg2-arg1 ;//différence absolue
  7. return diff<tolerance ;
  8. }
  9. void keyboard (char key, int x, int y){
  10. switch (toupper(key)){
  11. case 'D':nbr_degre+= 2.0; j=  0.0; k=  1.0; l= 0.0; break;//rotation Y
  12. case 'S':nbr_degre+= 2.0; j=  0.0; k= -1.0; l= 0.0; break;//rotation Y
  13. case 'E':nbr_degre+= 2.0; j= -1.0; k=  0.0; l= 0.0; break;//rotation X
  14. case 'X':nbr_degre+= 2.0; j=  1.0; k=  0.0; l= 0.0; break;//rotation X
  15. case 'O':c -= 0.5 ;                                 break;
  16. case 'I':c += 0.5 ;
  17.       if(fnear(c,10)){profondeur= 1; }
  18.  else if(fnear(c,20)){profondeur= 2; }
  19.  else if(fnear(c,30)){profondeur= 3; }
  20.  else if(fnear(c,40)){profondeur= 4; }
  21.  //if(c>10-tolerance && c<40+tolerance) profondeur= (int)c/10 ;
  22.                                                     break;//manquait, optionnel maintenant
  23. }
  24. glutPostRedisplay() ;
  25. }

Rassures-moi: il y a une raison pour que la ligne en commentaire ne fasse pas l'affaire ?

LeGreg Enfin, tu as de la chance parce que 0.5 est un bon candidat pour etre converti en flottant (1.0*2^-1 en binaire).
tu aurais choisi 0.1 ca n'aurait pas ete aussi evident.
 
combien font 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f ?
 

Code :
  1. float t = 0.0f;
  2. for (int i=0; i < 10; ++i) {t+=0.1f};
  3. assert (t == 1.0f)


Mon compilateur n'a pas l'air de savoir tres bien..
 
de toute facon il manque un break dans ton code original.
 
un autre truc: pourquoi tu recalcules profondeur quand tu decrementes c mais pas quand tu l'incrementes?
 
A+
LeGreg

Musaran

J'ai bêtement écrit a écrit :

Code :
  1. if(1.0/3.0 == 1.0/3.0)
  2. cout << "berk !\n" ;

affiche "berk !" chez moi, sans que je saches pourquoi !


:o Pour se moquer de moi c'est ici: http://www.presence-pc.com/sqlforu [...] 149&cat=11.
 
Mais ne ne nous dispersons pas et concentrons-nous sur ton problème.

kadreg

musaran a écrit a écrit :

 
A titre d'exemple, ceci :

Code :
  1. if(1.0/3.0 == 1.0/3.0)
  2. cout << "berk !\n" ;

affiche "berk !" chez moi, sans que je saches pourquoi !




 
Et qu'affiche ceci ? :
 

Code :
  1. if(3.0/9.0 == 1.0/3.0)
  2. cout << "berk !\n" ;
  3. else
  4. cout << "plop!\n" ;

Jar Jar

airseb a écrit a écrit :

 :non: nan nan moi yen a pas être bête  :non:


Peut-être, mais tu n'as toujours pas compris pourquoi il ne faut pas faire de tests d'égalité sur des flottants.

Musaran Le switch du C++ requiert une valeur entière: enum, bool, char, short, int, long...
Mêmes les pointeurs et type_info sont interdits.
Qui plus est, les case requièrent des constantes vraies, c-a-d connues à la compilation.
 

gilou a écrit a écrit :

case 1/3: n'est pas acceptable en C, car 1/3 est une expression a evaluer et non pas une constante.


Tous les termes étant constants, c'est une expression constante évaluée à la compilation, donc c'est acceptable.
Par contre attention: 1/3 vaut 0 ! Puisque les opérandes sont entiers, le résultat l'est aussi (troncage).
 
Les flottants ne sont pas exacts.
1.0/3.0 vaut 0.333..., qui *3 vaut 0.999... !
Normal que le swich les refuses, puisqu'il fait un test d'égalité.
A titre d'exemple, ceci :

Code :
  1. if(1.0/3.0 == 1.0/3.0)
  2. cout << "berk !\n" ;

affiche "berk !" chez moi, sans que je saches pourquoi !
 
Reste plus qu'a simuler un switch étendu avec if-else:

Code :
  1. switch(z){
  2. case a : /*a*/      ; break ;
  3. case b : /*b*/
  4. case c : /*c*/      ; break ;
  5. default: /*default*/; break ;
  6. }
  7. if     (z==a){      /*a*/            ;}
  8. else if(z==b){      /*b*/;goto tagc  ;}
  9. else if(z==c){tagc: /*c*/            ;}
  10. else         {      /*default*/      ;}

Avantage: le test peut être plus complexe qu'une simple égalité.
Inconvénient: le break est implicite.

airseb :lol:  
 
 :non: nan nan moi yen a pas être bête  :non:
HappyHarry

airseb a écrit a écrit :

ça marche bien  :sol:  




 
tetu, obstiné, et incrédule ... (un peu bete aussi  :D )

airseb ça marche bien  :sol:
Jar Jar

airseb a écrit a écrit :

ben ça marche  :p


Mais c'est dépendant de l'implémentation des flottants, et tu vas avoir des bugs qui vont surgir sans comprendre comment.

airseb ben ça marche  :p
kadreg

airseb a écrit a écrit :

c bon je l'ai fait avec un if  :D  :lol:  




 
if (c == 3.0) ? Fait gaffe, tu n'a fait que deplacer le problème.
 

airseb c bon je l'ai fait avec un if  :D  :lol:
gilou

legreg a écrit a écrit :

eheh la solution a tous vos problemes:

Code :
  1. switch(FToDw(monfloat)) {
  2. //..
  3. }


 
A+
LeGreg




Oui, ou alors il s'ecrit rapidement une fonction adaptée a son pb qui a un float en entrée et un int en sortie.
A+,

gilou

JyB a écrit a écrit :

 
 
Pas numérique : scalaire. Un char, un short, un integer, etc.
N'importe quoi qui soit une valeur discrète.
On ne peut pas faire de switch sur des types non-scalaires comme les float, les tableaux, les structs etc.




C'est pourquoi j'ai mis le second paragraphe. Mais au depart, j'avais trouvé des sites web ou le type requis etait "numerical" et non pas "integral" dans leur description de la syntaxe du langage C.
A+,

LeGreg Eh Airseb! c'est quoi que tu veux faire avec ton switch(c)?
 
Genre tu peux pas en déduire la profondeur avec la valeur de c?
 
LeGreg
 
kadreg

legreg a écrit a écrit :

eheh la solution a tous vos problemes




 
SpaDansLaNorme

LeGreg eheh la solution a tous vos problemes:

Code :
  1. switch(FToDw(monfloat)) {
  2. //..
  3. }


 
A+
LeGreg

JyB

gilou a écrit a écrit :

 
Ptet en C++, mais en C, on demande juste que ce sur quoi porte le switch soit de type numerique.




 
Pas numérique : scalaire. Un char, un short, un integer, etc.
N'importe quoi qui soit une valeur discrète.
On ne peut pas faire de switch sur des types non-scalaires comme les float, les tableaux, les structs etc.

gilou

Verdoux a écrit a écrit :

 
Si

The condition shall be of integral type, enumeration  type,  or  of  a
  class  type for which a single conversion function to integral or enu-
  meration type exists (_class.conv_).

http://www.comnets.rwth-aachen.de/doc/c++std/stmt.html




Ptet en C++, mais en C, on demande juste que ce sur quoi porte le switch soit de type numerique.
 
En fait, selon les liens internet que j'ai trouvé, il est dit que ce doit etre un type integral ou non. Je subodore que c'etait pas le cas au depart et que ca a evolué ensuite (ansi-c?) pour ajouter cette condition.
A+,

farib ben ca parait logique... si t'as un
 
 double Bidule;
 
tu fais jamais  
 
if (Bidule == 0)
 
mais if (Bidule < TOLERANCE)
 
avec la valeur absolue
verdoux

gilou a écrit a écrit :

 
Ben sauf que je viens de relire la spec, et je ne vois rien en C ou C++ qui s'oppose a l'utilisation de flottants dans ce cas.
Plutot une limitation du compilateur qu'il utilise, je pense.
A+,




Si

The condition shall be of integral type, enumeration  type,  or  of  a
  class  type for which a single conversion function to integral or enu-
  meration type exists (_class.conv_).

http://www.comnets.rwth-aachen.de/doc/c++std/stmt.html

gilou

Willyzekid a écrit a écrit :

Oui enfin, c'est logique aussi. Un nombre flottant, c'est par définition une valeur approximative. Du coup, on peut pas "sérieusement" écrire float1 == float2...D'ailleurs Ada 83 (ahah oui!! old school les amis), ne l'accepte pas comme ca! :)
Donc dans un switch où on ecrirait

Code :
  1. switch (c) {
  2.    case 1/3:
  3.    ....
  4. }


Ca me semble pas pas tip top.




Euh non.
Un nombre flottant n'est pas une expression approximative lorsqu'on travaille en C, justement etant donné le fait qu'on emploie le standard IEEE pour le representer.
d'autre part,  
case 1/3: n'est pas acceptable en C, car 1/3 est une expression a evaluer et non pas une constante.
A+,

Willyzekid Oui enfin, c'est logique aussi. Un nombre flottant, c'est par définition une valeur approximative. Du coup, on peut pas "sérieusement" écrire float1 == float2...D'ailleurs Ada 83 (ahah oui!! old school les amis), ne l'accepte pas comme ca! :)
Donc dans un switch où on ecrirait

Code :
  1. switch (c) {
  2.    case 1/3:
  3.    ....
  4. }


Ca me semble pas pas tip top.

Jar Jar Mais c'est vrai que je n'ai trouvé nulle part référence à cette impossibilité.
Ceci dit, la norme IEEE pour les flottants rend leur utilisation dans un switch complètement inappropriée.
Jar Jar

gilou a écrit a écrit :

Ben sauf que je viens de relire la spec, et je ne vois rien en C ou C++ qui s'oppose a l'utilisation de flottants dans ce cas.
Plutot une limitation du compilateur qu'il utilise, je pense.


En tout cas gcc n'en veut pas non plus, et je crois pourtant qu'il respecte la norme ISO C à 100 %.

gilou

Jar Jar a écrit a écrit :

Ça me paraît clair : tu fais un switch(c), et c est un flottant.




Ben sauf que je viens de relire la spec, et je ne vois rien en C ou C++ qui s'oppose a l'utilisation de flottants dans ce cas.
Plutot une limitation du compilateur qu'il utilise, je pense.
A+,

airseb

Jar Jar a écrit a écrit :

Réfléchis un peu : qu'est-ce qu'un flottant ?




 
 je sais c un nombre à virgule  :o  :D

lorill

airseb a écrit a écrit :

on a pas le droit de faire un switch avec un flottant ?
c absurde ! pourquoi on aurais pas le droit ?




 
parce que C2450. Je suis sur qu'en cherchant dans la norme ca doit etre expliqué.

Jar Jar

airseb a écrit a écrit :

on a pas le droit de faire un switch avec un flottant ?
c absurde ! pourquoi on aurais pas le droit ?


Réfléchis un peu : qu'est-ce qu'un flottant ?

airseb on a pas le droit de faire un switch avec un flottant ?
c absurde ! pourquoi on aurais pas le droit ?
lorill

airseb a écrit a écrit :

j'ai cette erreur là :
 
error C2450: switch expression of type 'float' is illegal
        Integral expression required




 
Ben le message est clair, non ?
 
Edit: grillé de 20 secondes

Jar Jar

airseb a écrit a écrit :

j'ai cette erreur là :
 
error C2450: switch expression of type 'float' is illegal
        Integral expression required


Ça me paraît clair : tu fais un switch(c), et c est un flottant.

airseb j'ai cette erreur là :
 
error C2450: switch expression of type 'float' is illegal
        Integral expression required
Jar Jar Tu peux expliquer en quoi ça ne marche pas exctement ?
airseb ya un peu d'open gl mais l'erreur est pas là.
 
float c = 0.0 ;
 
 
void keyboard (unsigned char key, int x, int y)
{
 
 
 
switch (key)  
{
case 'd' : //fait tourner selon l'axe des Y
case 'D' :
 
nbr_degre += 2.0;  
j = 0.0 ;
k = 1.0 ;
l = 0.0 ;
glutPostRedisplay () ;
break ;
 
case 's' :
case 'S' :
 
nbr_degre += 2.0; //fait tourner selon l'axe des Y
j = 0.0 ;
k = -1.0 ;
l = 0.0 ;
glutPostRedisplay () ;
break ;
 
case 'e' : //fait tourner selon l'axe des X
case 'E' :
 
nbr_degre += 2.0;
j = -1.0 ;
k = 0.0 ;
l = 0.0 ;
glutPostRedisplay () ;
break ;
 
case 'x' : //fait tourner selon l'axe des X
case 'X' :
 
nbr_degre += 2.0;
j = 1.0 ;
k = 0.0 ;
l = 0.0 ;
glutPostRedisplay () ;
break ;
 
case 'i':
case 'I':
 
c += 0.5 ;
switch (c)  
{
 case 10.0 :
 profondeur = 1 ;
 glutPostRedisplay () ;
 break ;
 
 case 20.0 :
 profondeur = 2 ;
 glutPostRedisplay () ;
 break ;
 
 case 30.0 :
 profondeur = 3 ;
 glutPostRedisplay () ;
 break ;
 
 case 40.0 :
 profondeur = 4 ;
 glutPostRedisplay () ;
 break ;
}
 
 
 
case 'o':
case 'O':
 
c -= 0.5 ;
glutPostRedisplay () ;
break ;
 
 
}
}
 

Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)