Calcul complement à 2

Calcul complement à 2 - C - Programmation

Marsh Posté le 19-08-2005 à 17:09:32    

Bonjour,
 
Débutant en C,
je voudrais concertir en C, un calcul tiré d'un programme en VB.
calcul de checkum (complement à 2 de la somme de 4 octets + 1).
 
Voici le calcul en VB:
checksum = (255 - ((((13 + address + Asc("S" ) + Asc("1" )) / 256) - Int((13 + address + Asc("S" ) + Asc("1" )) / 256)) * 256)) + 1
(address=1)
 
 
N'y a a t'il pas un moyen plus simple pour le faire en C ?
 
Sinon, je n'ai pas trouvé de fonction équivalente à 'int'.
La fonction "double floor(double x);" n'est pas trouvée par le compilateur même avec  
#include <math.h>  
 

Code :
  1. > gcc k8056_set1.c -o k8056_set1
  2. /tmp/ccp7XuN3.o: In function `checksum':
  3. k8056_set1.c:(.text+0x13a): undefined reference to `floor'
  4. collect2: ld returned 1 exit status


 
merci pour toutes info.

Reply

Marsh Posté le 19-08-2005 à 17:09:32   

Reply

Marsh Posté le 19-08-2005 à 17:11:54    

domos a écrit :

Sinon, je n'ai pas trouvé de fonction équivalente à 'int'.


 
Je suppose que c'est pour faire un cast : (int) devant la parenthèse

domos a écrit :

Code :
  1. > gcc k8056_set1.c -o k8056_set1
  2. /tmp/ccp7XuN3.o: In function `checksum':
  3. k8056_set1.c:(.text+0x13a): undefined reference to `floor'
  4. collect2: ld returned 1 exit status



 
Faut pas rajouter -lm à la compilation?

Reply

Marsh Posté le 19-08-2005 à 17:13:55    

Asc("S" ) ?

Reply

Marsh Posté le 19-08-2005 à 17:14:32    

int ?

Reply

Marsh Posté le 19-08-2005 à 18:01:00    

Taz a écrit :

int ?
Asc("S" ) ?


 
Int en basic donne la partie entière de la division.
 
asc("S" ) est le code asccii de 'S'
 
Ci-dessous exemple en basic (a,b,c,d sont  4 octets):

Code :
  1. (255 - ((((a + b + c + d) / 256) - Int((a + b + c + d) / 256)) * 256)) + 1
  2. ( 255 - ( ( ( (13 + 1 + 83 + 50) / 256 ) - Int( (13 + 1 + 83 + 49) / 256 ) ) * 256 ) ) + 1
  3. ( 255 - ( ( ( 147 / 256 ) - Int( 147 / 256 ) ) * 256 ) ) + 1 = 109
  4. ( 255 - ( ( 0,57421875 - Int( 0,57421875 ) ) * 256 ) ) + 1 = 109
  5. ( 255 - ( ( 0,57421875 - 0 ) * 256 ) ) + 1 = 109
  6.   255 - 147 + 1 = 109


 
voilà pour être plus clair.
 
merci

Reply

Marsh Posté le 19-08-2005 à 18:02:35    

et c'est quoi le problème ?

Reply

Marsh Posté le 19-08-2005 à 18:06:57    

Taz a écrit :

et c'est quoi le problème ?


 
je cherche à faire l'équivalent en C, sachant que je ne trouvais pas de fonction équivalente à 'Int'.

Reply

Marsh Posté le 19-08-2005 à 18:10:33    

ben soit tu castes ou tu utilises floor, où tu expliques pourquoi y un putain de float dans un calcul entier de checksum !

Reply

Marsh Posté le 19-08-2005 à 18:20:31    

Il fait des divisions, je présumme que le VB convertit les divisions d'entiers en flottants quand le résultat n'est pas entier (http://membres.lycos.fr/angel2k/petrus/xppetrus.gif)


Message édité par masklinn le 19-08-2005 à 18:20:47

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 19-08-2005 à 18:23:35    

Taz a écrit :

ben soit tu castes ou tu utilises floor, où tu expliques pourquoi y un putain de float dans un calcul entier de checksum !


 
Le calcul est fourni en exemple en VB pour envoyer des commandes sur une carte (kit velleman) par le port série.
Il y a 4 octets à envoyer à la carte + le checksum calculé comme dans l'exemple que j'ai donné.
 
Je suppose qu'il on fait comme cela dans le cas ou la somme (a+b+c+d) est supérieur à 256, le checksum serais négatif si il n'y avait la soustraction de la partie entière..
 
C'est pourquoi je cherchais une solution + simple en C...
 
 

Reply

Marsh Posté le 19-08-2005 à 18:23:35   

Reply

Marsh Posté le 19-08-2005 à 18:51:34    

(unsigned char) -(13+1+'S'+'1');
?
EDIT: il y a une faute dans ton calcul, un 50 a la place d'un 49


Message édité par mcjoedassin le 19-08-2005 à 18:53:42
Reply

Marsh Posté le 19-08-2005 à 18:56:34    

domos a écrit :

Le calcul est fourni en exemple en VB pour envoyer des commandes sur une carte (kit velleman) par le port série.
Il y a 4 octets à envoyer à la carte + le checksum calculé comme dans l'exemple que j'ai donné.
 
Je suppose qu'il on fait comme cela dans le cas ou la somme (a+b+c+d) est supérieur à 256, le checksum serais négatif si il n'y avait la soustraction de la partie entière..
 
C'est pourquoi je cherchais une solution + simple en C...


 
Je pense avoir trouvé.
en fait le calcul :
 

( 255 - ((((a + b + c + d) / 256) - Int((a + b + c + d) / 256)) * 256)) + 1


 
 revient à
 

( 255 - ((a+b+c+d) modulo 256) ) + 1


 
ce qui devrai être + simple à coder  
 
votre avis ?

Reply

Marsh Posté le 19-08-2005 à 20:07:23    

domos a écrit :

Je pense avoir trouvé.
en fait le calcul :
 

( 255 - ((((a + b + c + d) / 256) - Int((a + b + c + d) / 256)) * 256)) + 1


 
 revient à
 

( 255 - ((a+b+c+d) modulo 256) ) + 1


 
ce qui devrai être + simple à coder  
 
votre avis ?


C'est mieux. Effectivement, le checksum 8 bits c'est bien la somme modulo 256. Pour le complément à deux, on fait + 1 et on inverse les bits.
 

unsigned checksum_abcd = (~(((a + b + c + d) & ((1 << 8) - 1)) + 1)) & ((1 << 8) - 1);


(corrigé, merci 'mcjoedassin')


Message édité par Emmanuel Delahaye le 20-08-2005 à 01:01:26

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 19-08-2005 à 20:36:48    

Int((a + b + c + d) / 256)) * 256)
Diviser par 256 pour remultiplier par 256 ?
 
 :heink:  
 

Reply

Marsh Posté le 19-08-2005 à 20:53:08    

& (1 << 8);
 
resultat sur 1 bit :/

Reply

Marsh Posté le 19-08-2005 à 21:06:46    

mcjoedassin a écrit :

& (1 << 8);
 
resultat sur 1 bit :/


Beuh, ça m'apprendra à ne pas vérifier...

& ((1 << 8) - 1)


Je corrige...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 19-08-2005 à 23:00:16    

Emmanuel Delahaye a écrit :

C'est mieux. Effectivement, le checksum 8 bits c'est bien la somme modulo 256. Pour le complément à deux, on fait + 1 et on inverse les bits.
 

unsigned checksum_abcd = (~(((a + b + c + d) & (1 << 8)) + 1)) & ((1 << 8) - 1);


(corrigé, merci 'mcjoedassin')


 
Je n'ai pas réussi à obtenir les bons résultats avec ta méthode mais je m'en suis inspiré pour y arriver.
 
j'ai obtenu cela:
 

checksum = ~((a + b + c + d) & 0xFF) + 1 ;


 
Merci à tous pour votre aide
 
a+


Message édité par domos le 19-08-2005 à 23:43:38
Reply

Marsh Posté le 20-08-2005 à 11:27:38    

Tiens, y'a pas des convertisseurs VB -> C ?
 
[:neowen]


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed