[C] Rotation de bits sur la gauche (ROL)

Fermé
anais - 30 juin 2006 à 21:51
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 - 3 juil. 2006 à 13:14
Bonsoir !

Je cherche à recoder un programme en assembleur en C : pour le moment tout se passe bien, mais j'ai quelques soucis avec l'instruction rol (rotation de bits vers la gauche).

J'ai un nombre en hexadécimal qui est 65657247, et je veux effectuer un rol de 104 (en décimal) dessus. A la main, a la calculette et avec mon programme en assembleur j'obtiens : 65724765 (en hexa).

Je cherche donc à obtenir la même chose en C : d'après ce post : c rol j'ai un code qui ressemble à ça (sous dev c++) :

#include <stdio.h>
#define ROL(x,b) (((x) >> (b)) | ((x) << (32 - (b))))

int main(int argc, char * argv[])
{
int a = 0x65657247;

printf("%8.8x\n",  ROL(a,104));
system ("pause");

return 0;
}


A la compilation, j'obtiens : warning: right shift count >= width of type et warning: left shift count is negative
Je vois pas du tout d'ou vient le problème... qui pourrait m'aider à trouver le résultat attendu ?

Merci d'avance !

4 réponses

mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 812
1 juil. 2006 à 11:01
Vu ce qui est dit là :
https://www.squalenet.net/fr/ti/tutorial_c/8-operateurs-arithmetiques-et-bits-a-bits.php5

je dirais que c'est simplement :
#include <stdio.h>
#include <stdlib.h>

int main(){
  unsigned int x = 0x65657247;
  x << 104;
  printf("hex = %x\n",x);
  printf("dec = %d\n",x);
  getchar();
  return 0;
}

PS : evite d'utiliser les commande via system() qui vont faire que ton programme va dépendre de l'OS (windows ou linux), alors que getchar() fait pareil et marche avec tout le monde...

Bonne chance
0
Merci pour ta réponse, cependant, je crois que ton code ne fait qu'un décalage de bits vers la gauche (shl en asm), et non une rotation !
0
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 812
3 juil. 2006 à 00:38
Ok je viens de capter ce que tu faisais. Comme b = 104
1) ((x) >> (b)) entraine un décalage de 104 bits alors que l'entier est codé sur moins de bits (32 je suppose vu ce que tu as écris).
2) ((x) << (32 - (b))) à un décalage de 32-104 <= 0 bits

D'où les messages d'erreurs du compilateur. Il faudrait que tu utilises pour (1) un décalage de moins de 32 bits (en utilisant un opérateur modulo (% en C) ?), et pour deux une valeur absolue (par exemple à l'aide d'une autre macro) ?

Bonne chance
0
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
3 juil. 2006 à 13:14
Salut,

Ta macro ROL fait en fait un equivalent de ror en assembleur (rotation des bits vers la droite).

Si tu ne mets pas de constante dans b pour ta macro, le compilateur ne te mettra aucune alerte. D'ailleurs avec ta macro (si tu la corriges en un vrai rol), la rotation se fait très bien même avec de gros nombres (par contre on dirait qu'un rol en assembleur ne peut supporter d'opérande de plus de 255 pour la rotation, tandis que ta macro supportera plus.

Si tu as quand même des soucis, tu peux utiliser une fonction qui découpe la rotation en plusieurs rotations distinctes de moins de 32 bits. Un exemple:
#include <stdio.h>
// Ta rotation ror corrigée en rol
#define ROL32(x,b) (((x) << (b)) | ((x) >> (32 - (b))))

//La rotation en assembleur
unsigned int test_asm()
{
	__asm__("movl $100, %eax\n\t"
	        "roll  $255, %eax"
	        );
}

// La rotation découpée en plusieurs rotations distinctes
unsigned int rol(unsigned int nb, unsigned int r)
{
	for (; r>31; r-=31)
	{
		nb = ROL32(nb, 31);
	}
	nb = ROL32(nb, r);
	return nb;
}

int main(int argc, char **argv)
{
	unsigned int a=100;
	unsigned int r=255;
        //Affichage de la rotation en assembleur
	printf("%u\n", test_asm() );
        //Affichage de la rotation en C
        //Marche aussi, chez moi, avec printf("%u\n", ROL32(a,r) );
	printf("%u\n", rol(a,r) );
	return 0;
}
-1