cs_jb60
Messages postés55Date d'inscriptionmardi 16 septembre 2003StatutMembreDernière intervention 4 août 2008
-
9 sept. 2004 à 20:15
racpp
Messages postés1909Date d'inscriptionvendredi 18 juin 2004StatutModérateurDernière intervention14 novembre 2014
-
10 sept. 2004 à 16:07
Bonjour,
Hier, je me faisais un petit programme pour afficher un nombre en binaire.
Je voulais faire ça sur un char, un int, et un double.
Je me suis servi des décalages binaires >> et <<.
Or, tout va bien quand je fais ce décalage sur un char ou sur un int, mais lorsque je veux faire ce décalage binaire sur un double, le compilo me met un message d'erreur, comme-ci il ne pouvait pas calculer ce décalage binaire.
Comment ça se fait?
Vous êtes d'accord avec moi que l'on est censé pouvoir faire un décalage binaire sur un double qui devrait pouvoir aller jusqu'à un décalage de 64 bits dans les deux sens (>>64 et <<64), non?
Ou alors je ne comprends pas tout sur le décalage binaire, ça aurait peut être à voir avec l'architecture de Windows qui utilise seulement 32 bits? Mais alors, je ne comprends toujours pas, car même sur 64 bits, on devrait pouvoir décaler les bits, car les cases mémoires sont censées être à côté, non?
Voilà, je suppose que vous avez compris mon interrogation, alors j'attends vos réponses SVP.
vecchio56
Messages postés6535Date d'inscriptionlundi 16 décembre 2002StatutMembreDernière intervention22 août 201014 9 sept. 2004 à 23:37
oui, c'est 1b
1 en binaire c'est que des zéros, sauf un 1 en poids faible, y rien a conprendre.
Modulo 2 en base 2, c'est comme modulo 10 en base 10, tu prends le 'digit de droite' en gros.
(Note que dans l'exemple que j'ai donné au début, le nombre s'écrit a l'envers: le PF est a droite).
DeAtHCrAsH
Messages postés2670Date d'inscriptionvendredi 25 janvier 2002StatutMembreDernière intervention 6 février 2013 9 sept. 2004 à 23:41
vecchio56> J'crois bien que tu n'y a encore moins compris que moi ou alors t'es un étourdi parceque "i >> 2 &1" ca fait aussi 1b!
T'es sure d'avoir bien compris la chose ?
Parceque t'es explications sont confuses et c'est peut etre aussi confus dans ta tete :/
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 9 sept. 2004 à 23:57
vecchio, le bit PF (le vrai) n'a rien a voir avec le fait qu'un nombre soit pair ou impair, il indique s'il y a un nombre pair de bits positionnes dans la derniere valeur manipulee.
ciao...
BruNews, Admin CS, MVP VC++
Vous n’avez pas trouvé la réponse que vous recherchez ?
DeAtHCrAsH
Messages postés2670Date d'inscriptionvendredi 25 janvier 2002StatutMembreDernière intervention 6 février 2013 10 sept. 2004 à 00:18
vecchio56> t'es un prof du marché au puce ma parole. T'embrouilles plus qu'autre chose mais merci quand meme d'avoir essayé.
Bon je pense avoir compris le systeme.
Voici une explication simple a ce calcul tout "bete":
Les opérateurs ">>" et "&" sont de meme priorité.
La lecture se fait donc de gauche vers la droite sans calcul intermediaire.
L'opérateur ">>" permet de décaler des bits vers la droite.L'opérateur "&" retourne 1 si les deux bits de même poids sont à 1 (ex : 3 & 5 1 car 011 & 101 1)
Soit dans notre calcul i = i >> 2 & 1 avec i=4 on a :
1) 4 = 100b
2) On applique le décalage et on obtient 001b soit 1 en décimal.
3) On compare les bits de meme poids entre 001b et 001b (qui correspond a notre 1 dans "& 1").
4) On obtient ainsi 001b.
CONCLUSION: i=1 ou i=001b et 32 post sur le forum pour comprendre le principe de la chose.! Ouf!
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 10 sept. 2004 à 00:53
exemple tout bete pour les dates par exemple.
Si on 'pack' une date dans un DWORD:
en simili hexa: 0xAAAAMMYY
alors on peut se servir illico des '==', '>=' etc, tres performant pour ecrire un agenda.
SYSTEMTIME st;
DWORD d; // une date
d = st.wYear;
d <<= 8;
d |= (DWORD) st.wMonth;
d <<= 8;
d |= (DWORD) st.wDay;
cs_eRoZion
Messages postés241Date d'inscriptionvendredi 23 mai 2003StatutMembreDernière intervention 8 octobre 20071 10 sept. 2004 à 02:06
DeAtHCrAsH > "L'opérateur "&" retourne 1 si les deux bits de même poids sont à 1"
C'est faux, retourne 1 si le bit de poids faible est allumé.
DeAtHCrAsH > "Au fait dans quel genre d'application on peut etre ammené a utiliser le décalage de bits et plus générallement travailler en binaire sur des bits ?"
Un cas très bête est celui d'un soft qui doit stoqué un état qui ne peut être que A ou B (genre ampoule allumée, ampoule éteinte, pixel allumé, pixel éteint), et bien tu peux stoquer cet état sur 1 seul bit au lieu de 32 si tu utilise un int normal.
BruNews > "vecchio, le bit PF (le vrai) n'a rien a voir avec le fait qu'un nombre soit pair ou impair, il indique s'il y a un nombre pair de bits positionnes dans la derniere valeur manipulee."
Certainement que tu dois avoir raison dans un cas particulier, mais en ce qui concerne le fait que le bit de poid fort indique la parité dans un stoquage mémoire, et bien je ne pense pas ma tromper en disant que c'est vrai pour un 'signed', mais pas pour un 'unsigned', ce qui explique qu'un 'signed' ne puisse monter que jusqu'à ((2^31)-1) en positif, alors qu'un 'unsigned' peut grimper jusqu'à ((2^32)-1) toujours en positif.
En revance, tous deux possèdent 2^32 états distincts.
NB: Dans un 'signed', si le bit lourd est allumé, alors le chiffre est négatif et est calculé en faisant la somme des bits éteints !!! et non pas allumés.
Les autres >
Bon, ce truc faut faire attention sur quelle machine on s'en sert, l'exemple donné par vecchio tourne en lowendian, soit le bit de poids faible à droite.
Pour une utilisation sur mac (bigendian), faut juste remplacé l'opérateur '>>' par '<<'.
Exemple sur un chiffre à 8 bits appelé 'Chiffre' (exemple lowendian) :
76543210 /*position */
HGFEDCBA /* bits */
">>" fait péter le bit de droite (position 0) et décale les autres d'un cran vers la droite (leur position est diminuée de 1). Bit[1] devient donc Bit[0], etc...
"&1" teste le bit en position 0 (le plus à droite), le résultat vaut 0 si le bit est eteint (0) et 1 s'il est allumé (1), soit la valeur du bit (en position 0).
On applique la formule (*p >> i & 1) ou *p pointe sur 'Chiffre' :
***On commence avec i=0
_Chiffre >> i =
76543210 /*position */
HGFEDCBA /* bits */
_Resultat&1 = A
***On continu avec i=1
_Chiffre >> i =
6543210 /*position */
HGFEDCB /* bits */
_Resultat&1 = B
***On continu avec i=2
_Chiffre >> i =
543210 /*position */
HGFEDC /* bits */
_Resultat&1 = C
Et ainsi de suite, sur pc, vous avez la valeur binaire de 'Chiffre' qui s'affiche de gauche à droite dans l'ordre inverse du stoquage mémoire, soit sous la forme ABCDEFGH (noté que sur mac c'est directement dans le bon sens avec '<<').
Pour palier à ce problème sur pc, pour l'afficher en HGFEDCBA, soit sous sa forme mémoire:
int main()
{
float f = 3.14159f; // 32 bits
int* p = (int*)&f, i;
char b[32];
for(i = 0; i < 32; i++)
b[31-i]=((*p >> i) & 1);
for(i = 0; i < 32; i++)
printf("%d", b[i]);
return(0);
}
cs_eRoZion
Messages postés241Date d'inscriptionvendredi 23 mai 2003StatutMembreDernière intervention 8 octobre 20071 10 sept. 2004 à 02:09
Correction :
"En revance, tous deux possèdent 2^32 états distincts.
NB: Dans un 'signed', si le bit lourd est allumé, alors le chiffre est négatif et est calculé en faisant la somme DES PUISSANCES DE DEUX des bits éteints !!! et non pas allumés."
racpp
Messages postés1909Date d'inscriptionvendredi 18 juin 2004StatutModérateurDernière intervention14 novembre 201417 10 sept. 2004 à 02:17
Salut,
On utilise aussi le décalage pour multiplier ou diviser des entiers par 2, 4, 8, 16 etc. Chaque décalage vers la gauche est une multiplication par 2 et vers la droite une division. Au niveau du microprocesseur, une instruction de décalage est beacoup plus rapide qu'une multiplication. Il existe une autre variante du décalage, c'est la rotation. Le bit qui sort n'est pas perdu. Il rentre rentre dans le nombre de l'autre côté. La rotation est très utilisée dans les systèmes de cryptage de données. Il n'existe aucun opérateur pour la rotation en Visual C++. Je ne sais pas si c'est pareil pour les autres compilateurs.
racpp
Messages postés1909Date d'inscriptionvendredi 18 juin 2004StatutModérateurDernière intervention14 novembre 201417 10 sept. 2004 à 03:18
djl > La multiplication ou division par décalage n'est valable que pour les multiples de 2 (par 2, 4, 8 etc). On ne peut pas utiliser le décalage pour multiplier par 3 exemple. Le microprocesseur, par défaur, utilise les instructions du genre MUL ou DIV qui nécessitent beaucoup de cycles d'horloge. J'ai appris cela en programmant en assembleur pour des applications optimisées en vitesse. On nous conseillait toujours de choisir le décalage quand il s'agit d'une multiplication ou division par un multiple de 2.
racpp
Messages postés1909Date d'inscriptionvendredi 18 juin 2004StatutModérateurDernière intervention14 novembre 201417 10 sept. 2004 à 03:59
djl > Tu as raison, le compilateur transforme les multiplications ou division par 2, 4, etc par des décalages. Je viens de faire des tests en examinant le code assemleur engendré. C'est très intelligent de sa part. Il a mis SHL pour une multiplication par 2 et IMUL pour une multiplication par 3. Il est conscient de la supériorité en vitesse de SHL sur MUL dans le cas des multiplications par 2, 4 etc...