Inverser partie haute et partie basse d'un long

Inverser partie haute et partie basse d'un long - C++ - Programmation

Marsh Posté le 12-12-2002 à 11:45:13    

Voila ce que je cherche à faire :
inverser la partie haute et la partie passe d'un long.
Donc : passer les 4 premier octets en dernier et les 4 derniers en 1er. De sorte que 0xAB802453 devienne 0x2453AB80 (c pour un codage).
J'extrait la partie haut et la partie basse de mon long de la façon suivante :

Code :
  1. long SwapLowPartHighPart (long _l)
  2. {
  3.     long lHighPart = _l & 0xFFFF0000;
  4.     cout << "\nHighPart : " << lHighPart;
  5.     long lLowPart  = _l & 0x0000FFFF;
  6.     cout << "\nLowPart  : " << lLowPart;
  7.     // Marche pas, évidement ça reconstitue mon long d'origine !
  8.     return (lHighPart & lLowPart);
  9. }

Reply

Marsh Posté le 12-12-2002 à 11:45:13   

Reply

Marsh Posté le 12-12-2002 à 11:55:59    

>>    return (lHighPart & lLowPart);
 
ça devrait être un | ...
 
ensuite, tu décales les parties de 16 bits chacune dans un sens :
 
long lHighPart = (_l & 0xFFFF0000) >> 16;  
long lLowPart  = (_l & 0x0000FFFF) << 16;  

Reply

Marsh Posté le 12-12-2002 à 11:57:05    

manque peut etre le decalage :ange:
 
Edit : Ce qui devrait donner  
 

Code :
  1. return (((lHighPart>>16)& 0x0000FFFF) | ((lLowPart<<16) & 0xFFFF0000));


Message édité par VisualC++ le 12-12-2002 à 12:01:38
Reply

Marsh Posté le 12-12-2002 à 12:01:04    

en espérant que tes long sont evidemment sur 32bits


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 12-12-2002 à 12:04:05    

Taz@PPC a écrit :

en espérant que tes long sont evidemment sur 32bits


 
Sous Win32, c'est forcément sur 32 bits un long je crois !

Reply

Marsh Posté le 12-12-2002 à 12:05:39    

Merci.
qd même j'arrive pas à comprendre pourquoi il faut décaler, pour la partie basse. Pour la partie haute je trouve ça logique, ms pr la partie basse g du mal. Enfin bref, merci beaucoup.

Reply

Marsh Posté le 12-12-2002 à 12:06:53    

El_Gringo a écrit :

Merci.
qd même j'arrive pas à comprendre pourquoi il faut décaler, pour la partie basse. Pour la partie haute je trouve ça logique, ms pr la partie basse g du mal. Enfin bref, merci beaucoup.


ben parce que sinon tu vas avoir toute ton infos sur les 16 mêmes bits, et quand tu vas appliquer le | tu vas un peu perdre tout ca...

Reply

Marsh Posté le 12-12-2002 à 12:09:13    

lorill a écrit :


ben parce que sinon tu vas avoir toute ton infos sur les 16 mêmes bits, et quand tu vas appliquer le | tu vas un peu perdre tout ca...


 
Ouais, mais le décalage de la partie haute devrait suffire.
comme j'ai fait ici :
http://forum.hardware.fr/forum2.ph [...] t=#t267915

Reply

Marsh Posté le 12-12-2002 à 12:10:22    

Du coup, mon truc est presque bon !? il faudrais que je fasse comme ça, c ça ?

Code :
  1. long lHighPart = _l & 0xFFFF0000;
  2.       cout << "\nHighPart : " << lHighPart;
  3.       long lLowPart  = _l & 0x0000FFFF;
  4.       cout << "\nLowPart  : " << lLowPart;
  5.  
  6.       long lToReturn = lHighPart << 16;
  7.       lToReturn     |= lLowPart >> 16;

Reply

Marsh Posté le 12-12-2002 à 12:13:46    

transformer 0x12345678 en 0x56781234  
 
hi = 0x12345678 & ffff0000
hi = 0x12340000
 
lo = 0x12345678 & 0000fffff
lo = 0x00005678
 
faire un | de ces deux parties va donner le nombre d'origine.
 
hi = hi >> 16
hi = 0x00001234
 
lo = lo << 16
lo = 0x56780000
 
reverse = hi | lo = 0x56781234

Reply

Marsh Posté le 12-12-2002 à 12:13:46   

Reply

Marsh Posté le 12-12-2002 à 12:14:55    

El_Gringo a écrit :

     long lToReturn = lHighPart << 16;
      lToReturn     |= lLowPart >> 16;

c'est l'inverse. tu n'as jamais fait de binaire ?

Reply

Marsh Posté le 12-12-2002 à 12:15:54    

youdontcare a écrit :

transformer 0x12345678 en 0x56781234  
 
hi = 0x12345678 & ffff0000
hi = 0x12340000
 
lo = 0x12345678 & 0000fffff
lo = 0x00005678
 
faire un | de ces deux parties va donner le nombre d'origine.
 
hi = hi >> 16
hi = 0x00001234
 
lo = lo << 16
lo = 0x56780000
 
reverse = hi | lo = 0x56781234


 
Génial, j'ai compris. Merci...

Reply

Marsh Posté le 12-12-2002 à 12:16:07    

youdontcare a écrit :

c'est l'inverse. tu n'as jamais fait de binaire ?


 
...si peu !

Reply

Marsh Posté le 12-12-2002 à 12:17:58    

je te conseille un week-end romantique avec les opérations logiques ...

Reply

Marsh Posté le 12-12-2002 à 12:20:42    

youdontcare a écrit :

je te conseille un week-end romantique avec les opérations logiques ...


 
Ce week end, c'est avce ma copine normalement, j'crois qu'elle le prendrais mal si j'décommandais pour les opérations logiques (jalousie oblige :D)
Merci à tous  :hello:

Reply

Marsh Posté le 12-12-2002 à 13:21:39    

heu... un long c pas codé sur 4 octets ?!?


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 12-12-2002 à 13:43:03    

blackgoddess a écrit :

heu... un long c pas codé sur 4 octets ?!?


 
c'est code sur (CHAR_BIT * sizeof long) bits exactement


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 12-12-2002 à 14:03:51    

blackgoddess a écrit :

heu... un long c pas codé sur 4 octets ?!?


 
Ben, dans ce cas là en tout cas, c'est ce qu'on considère...
32 bits quoi !

Reply

Marsh Posté le 12-12-2002 à 17:56:54    

bin alors : l'auteur du sujet (el_gringo) dit :
 
inverser la partie haute et la partie passe d'un long.
Donc : passer les 4 premier octets en dernier et les 4 derniers en 1er. De sorte que 0xAB802453 devienne 0x2453AB80 (c pour un codage).
 
il a confondu octets avec chiffre hexa alors ?
 
enfin ... p-e si j'avais lu le topique en entier ca irait mieux ... :p
 
et si on fait :
 
long LongAInverser;
 
char tmp[2];
 
memcpy((void*)tmp,((void*)((&LongAInverser)+2),2);
memcpy(((void*)((&LongAInverser)+2),((void*)(&LongAInverser),2);
memcpy(((void*)(&LongAInverser),((void*)tmp,2);
 
(enfin c la théorie, g pas chercher à compiler ni rien, en fait ca serait de copier directement les 2 1ers octets à la place des 2 derniers et inversement)


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 12-12-2002 à 19:12:03    

Et comme ça, c'est pas plus propre ?
 

Code :
  1. #include <iostream>
  2. union swaplong
  3. {
  4.         struct
  5.         {
  6.                 unsigned short hi;
  7.                 unsigned short lo;
  8.         } x;
  9.         long y;
  10. };
  11. template <class T> void swap(T& a, T& b)
  12. {
  13.         T c;
  14.         c = a;
  15.         a = b;
  16.         b = c;
  17. }
  18. int main()
  19. {
  20.         swaplong a;
  21.         a.y  = 0x12345678;
  22.         swap(a.x.hi, a.x.lo);
  23.         std::cout << std::hex << a.y << "\n";
  24.         return 0;
  25. }

Reply

Marsh Posté le 13-12-2002 à 09:13:40    

BlackGoddess a écrit :

bin alors : l'auteur du sujet (el_gringo) dit :
 
inverser la partie haute et la partie passe d'un long.
Donc : passer les 4 premier octets en dernier et les 4 derniers en 1er. De sorte que 0xAB802453 devienne 0x2453AB80 (c pour un codage).
 
il a confondu octets avec chiffre hexa alors ?
 
enfin ... p-e si j'avais lu le topique en entier ca irait mieux ... :p
 
et si on fait :
 
long LongAInverser;
 
char tmp[2];
 
memcpy((void*)tmp,((void*)((&LongAInverser)+2),2);
memcpy(((void*)((&LongAInverser)+2),((void*)(&LongAInverser),2);
memcpy(((void*)(&LongAInverser),((void*)tmp,2);
 
(enfin c la théorie, g pas chercher à compiler ni rien, en fait ca serait de copier directement les 2 1ers octets à la place des 2 derniers et inversement)


 
Ben, El_Gringo il pense que dans 0x11223344, 11 est un octet, 22 un autre, 33 encore un, et 44 le dernier...

Reply

Marsh Posté le 14-12-2002 à 02:44:33    

Ça serait trivial si on disposait de l'opérateur de rotation:

Code :
  1. long swaphalves(long l){
  2. return l <<< (sizeof(long)*CHAR_BIT/2) ; //ou >>>
  3. }


Comme d'habitude ,il y a sûrement des librairies qui font ça très bien.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 14-12-2002 à 22:49:40    

"si on disposait" mais alors ca existe ton code ?


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 15-12-2002 à 00:24:49    

non


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 15-12-2002 à 04:16:00    

<<< existe en Java il me semble.
Et il me semble aussi qu'il a d'abord demandé dans la rubrique Java, donc ça peut lui servir.
 
Pour disposer de la rotation, il faudrait une librairie capable d'utiliser les instructions assembleur si elles existent.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 15-12-2002 à 11:15:19    

Musaran a écrit :

<<< existe en Java il me semble.
Et il me semble aussi qu'il a d'abord demandé dans la rubrique Java, donc ça peut lui servir.
 
Pour disposer de la rotation, il faudrait une librairie capable d'utiliser les instructions assembleur si elles existent.

oui, il existe mais ce n'est pas la rotation, il me semble. je crois que c'est un histoire de décalage avec un injection de 1


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 15-12-2002 à 12:09:22    

qq1 pourrait-il me donner un lien ou m'expliquer les << >> je c kil le faut ds cout par exemple mais je n'ai jms compris sa signification.


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 15-12-2002 à 12:10:30    

mais la c'est la surcharge d'opérateur. le << des ostream n'a rien à voir avec le << qu'on utilise sur des int


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 15-12-2002 à 12:23:45    

ah ... bin qq1 pourrait-il m'expliquer les 2 ou me donner un lien svp ?


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 15-12-2002 à 12:26:01    

ben pour les ostream c'est une surcharge, ca signifie juste "ecrire la representation de truc dans le flux"
 
pour les int, c'est un décalage binaire vers la gauche
 
i=1
 
j=i << 2
 
j==4


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 15-12-2002 à 12:37:53    

ok, d'accord, merci :)))
 
je suppose que >> décale les bits vers la droite ?


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 15-12-2002 à 12:39:07    

et au fait pour j = i << 2
le bit tout à gauche passe à droite ou il est viré e tle bit rajouté à droite est tjs un 0 ?


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 15-12-2002 à 16:00:15    

BlackGoddess a écrit :

et au fait pour j = i << 2
le bit tout à gauche passe à droite ou il est viré e tle bit rajouté à droite est tjs un 0 ?

avec << les bits de droite sont perdus et des 0 sont injectés par la gauche. c'est valable pour les type signés et non signés (signed et unsigned)
 
pour >>, sur les types non-signés, des 0 sont injectés par la droite. les bits de gauche sont perdus.
par contre sur les types signés (int par exemple), les bits injectes a droite peuvent etre 1 ou 0 selon la machine: ce n'est pas défini par la norme, donc attention


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 15-12-2002 à 18:30:37    

ok, mci bcp :)


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 15-12-2002 à 18:38:21    

Taz@PPC a écrit :

avec << les bits de droite sont perdus et des 0 sont injectés par la gauche. c'est valable pour les type signés et non signés (signed et unsigned)
 
pour >>, sur les types non-signés, des 0 sont injectés par la droite. les bits de gauche sont perdus.
par contre sur les types signés (int par exemple), les bits injectes a droite peuvent etre 1 ou 0 selon la machine: ce n'est pas défini par la norme, donc attention


 
Il me semblait que sur les types signés, >> devait conservé le signe et donc que >> recopie le bit de poit fort pour cela.

Reply

Marsh Posté le 15-12-2002 à 19:03:56    

non (je paraphrase le K&R chapitre 2.9)
 
selon la plateforme, il s'agit donc soit d'un décalage logique soit arithmétique.


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 16-12-2002 à 05:09:09    

Taz@PPC a écrit :

avec << les bits de droite sont perdus et des 0 sont injectés par la gauche. c'est valable pour les type signés et non signés (signed et unsigned)
 
pour >>, sur les types non-signés, des 0 sont injectés par la droite. les bits de gauche sont perdus.
par contre sur les types signés (int par exemple), les bits injectes a droite peuvent etre 1 ou 0 selon la machine: ce n'est pas défini par la norme, donc attention

Grand boutiste, va !
 
Il faut permuter gauche et droite. Les poids faibles sont conceptuellement placés à droite, quel que soit le boutisme du système.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 16-12-2002 à 08:09:11    

ben ouais  :pt1cable:


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 16-12-2002 à 12:13:00    

Musaran a écrit :

Grand boutiste, va !
 
Il faut permuter gauche et droite. Les poids faibles sont conceptuellement placés à droite, quel que soit le boutisme du système.


 
oui, parce que reellement, il faudrait savoir comment sont placées les barrettes memoires dans la machine :D

Reply

Marsh Posté le 16-12-2002 à 12:19:27    

ah ... bien ... c koi le boutisme ?


---------------
-( BlackGoddess )-
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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