Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

Conversion ou cast !
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#1 Message par Jérémy » dim. 29 janv. 2017 20:59

Bonsoir à tous,

Je ne comprends pas un truc !

Je suis obligé de déclarer une variable en INT alors que celle ci ne depassera jamais 255 ! sinon le calcul renvoyer est FAUX !!

Je m'explique :

Je recois par sms l'heure les minutes et les secondes , à la reception je les stock dans un tableau par INT Rx UART .

Ensuite je recupere chaques cases pour calculer le temps en secondes que je stock dans un unsigned long que j'appelle "chrono" .

Ensuite je souhaite envoyer ce "chrono" par texto donc je dois faire le sens inverse !

voila ce que ca donne .

Code : Tout sélectionner


char T_Chrono
[15]={0};
unsigned int Heures, Minutes, secondes;


la partie calcul du "chrono" dans le main ( en mode simplifiée ):

Code : Tout sélectionner

       if ( F_chrono){
            F_chrono = 0;
            //--- récupération et calcul du Chrono en seconde
            Heures = ((T_Chrono[0]-48)*10) + (T_Chrono[1]-48);
            Minutes = ((T_Chrono[2]-48)*10) + (T_Chrono[3]-48);
            Secondes = ((T_Chrono[4]-48)*10) + (T_Chrono[5]-48);
            
            Chrono 
= ( (Heures*3600) + (Minutes*60) + Secondes );
           
               composition_message
(1);
             }
         }


La fonction composition_message simplifiée aussi :

Code : Tout sélectionner

//------------------------------------------------------------------------------
void composition_message(char numero_message){

  char Compteur=0, Compteur2=0;
  char temp[30];

  F_envoi_ok=0;
  T_message[0] = 0;    // On commence la chaine par un NULL afin de pouvoir y ajouter la suite

  //--------------------    séléction et Création du message      -------------------
  switch (numero_message){

         case 1:{
                  strcat(T_message, "Valeurs recues:\r\n");
                  ShortToStr (Heures, temp);
                  strcat(T_message, temp );
                  strcat(T_message, "h");
                  ShortToStr (Minutes, temp);
                  strcat(T_message, temp );
                  strcat(T_message, "m");
                  ShortToStr (Secondes, temp);
                  strcat(T_message, temp );
                  strcat(T_message, "s\r\n");

                  LongWordToStr(Chrono, temp);
                  strcat(T_message, temp );
                  strcat(T_message, "s\r\n");
                  
                  strcat
(T_message, "Voulez-vous le lancer ?");
                  strcat(T_message, 0);  // On termine par un terminateur
                }


dans cette configuration ça fonctionne .

Mais si je mets char Heures, Minutes, secondes; le résultat est mauvais et je ne comprends pas pourquoi !

merci à vous si vous avez une explication
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Conversion ou cast !
brunog
Membre
Membre
Messages : 20
Enregistré en : janvier 2017

#2 Message par brunog » dim. 29 janv. 2017 21:32

Jérémy a écrit :Source du message        if ( F_chrono){
            F_chrono = 0;
            //--- récupération et calcul du Chrono en seconde
            Heures = ((T_Chrono[0]-48)*10) + (T_Chrono[1]-48);
            Minutes = ((T_Chrono[2]-48)*10) + (T_Chrono[3]-48);
            Secondes = ((T_Chrono[4]-48)*10) + (T_Chrono[5]-48);
            
            Chrono = ( (Heures*3600) + (Minutes*60) + Secondes );
           
               composition_message(1);
             }
         } 


Hello,
le langage C ne fait pas de surclassement automatique, ainsi par exemple si Heures est de type unsigned char, l'expression Heure * 3600 sera évaluée avec l'arithmétique unsigned char et le résultat ne sera pas celui attendu
A+,
BrunoG
---
Quelques pico-idées en vrac : http:://www.micro-examples.com

Conversion ou cast !
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#3 Message par Jérémy » dim. 29 janv. 2017 21:42

J'avoue ne pas comprendre oops

Je stock ce résultat dans un unsigned long ! je pensais que cela ne posais pas de problème. Seulement si le stockage est inférieur au résultat !!

Mais apparemment j'étais dans l'erreur !

Donc la variable "Heures" doit être du type pour stocker son résultat après la multiplication , c'est bien ca ?
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Conversion ou cast !
brunog
Membre
Membre
Messages : 20
Enregistré en : janvier 2017

#4 Message par brunog » dim. 29 janv. 2017 22:34

le type du membre de gauche d'une affectation ne détermine pas l'arithmétique du membre de droite
Jérémy a écrit :Source du message Donc la variable "Heures" doit être du type pour stocker son résultat après la multiplication , c'est bien ca ?

oui, ou sinon faire un type cast pour indiquer au compilateur l'arithmétique à utiliser et la nature du stockage du résultat intermédiaire, par exemple :

Code : Tout sélectionner

(unsigned int)Heures*3600
A+,
BrunoG
---
Quelques pico-idées en vrac : http:://www.micro-examples.com

Conversion ou cast !
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#5 Message par Jérémy » lun. 30 janv. 2017 08:29

Ok !!

Merci ! Beaucoup !

Je vais donc déclarer directement mes varaibles en unsigned intce sera plus simple pour moi !
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Conversion ou cast !
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2597
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#6 Message par paulfjujo » lun. 30 janv. 2017 09:09

bonjour,


le compilateur MikroC sait gerer (un peu) les dépassement de format
ex:

Code : Tout sélectionner

unsigned char c1
unisgned int k
;
c1=18;
k=c1*3600
result k
=64800


mais si tu geres l'heure au format 24H au lieu de 12H AM PM
tu auras un probleme des 19H00

Code : Tout sélectionner


c1
=19;
k=2846 

debordement du int car 
> 65535  .. là le compilo n'y peut rien 


mais l'usage d'un cast est une tres bonne habitude , au cas ou le compilo ( ou le programmeur ) s'y perdrait un peu
unsigned long L;
L=(unsigned long) c1 *3600;
...
Aide toi, le ciel ou FantasPic t'aidera

Conversion ou cast !
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#7 Message par Jérémy » mar. 31 janv. 2017 09:25

Merci ! pour ce complément d'infos
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Conversion ou cast !
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#8 Message par Jérémy » mar. 31 janv. 2017 10:20

J'ai opté au final pour cette solution suite à vos conseils

Ainsi je déclare mes variables en char , car les valeurs ne dépassent jamais les 255

Code : Tout sélectionner

char HeuresMinutessecondes


et ensuite je CAST seulement les "Heures" qui atteignent 99*3600=356400 au max ! donc en Long
ça donne :

Code : Tout sélectionner

Chrono = ( ((unsigned long)Heures*3600) + (Minutes*60) + Secondes ); 


Je test ca dés que je peux ! ( besoin du tel de ma femme qui est en train de dévaler les pistes de ski !)
C'est en faisant des erreurs, que l'on apprend le mieux !!!


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 61 invités