Page 1 sur 2
Syntaxe : Rotation à droite ou à gauche
Publié : mer. 19/avr./2006 13:36
par brossden
Bonjour à tous
J'ai un petit problème je n'arrive plus à retrouver la syntaxe pour réaliser la rotation à droite ou à gauche sur un octet ou sur un mot !
Merci de ne pas m'en vouloir d'avoir un problème de mémoire !

Publié : mer. 19/avr./2006 13:50
par brossden
J'ai trouvé tout seul !
La solution X>>n et X<<n
exemple :
debug 4>>1 donnne 2 soit en binaire : 100 devient 010
debug 4>>2 donnne 1 soit en binaire : 100 devient 001
debug 4<<1 donnne 8 en binaire soit : 100 devient 1000
debug 4<<2 donnne 16 en binaire soit : 100 devient 10000
Publié : mer. 19/avr./2006 14:14
par Anonyme
Au risque de paraître idiot, a quoi sert exactement les rotations?
Merci.
Publié : mer. 19/avr./2006 14:25
par brossden
Mais on est jamais idiot en posant une question
la rotation de 1 bit (plutot le décalage) à droite ou sert à diviser par 2
et à gauche à multiplier par deux. C'est trés rapide mais attention aux debordements ! et changements de signes !!
C'est quand même réservé aux développeur avertis !
Publié : mer. 19/avr./2006 15:19
par comtois
Ou faire du traitement d'image en récupérant les composantes d'une couleur , ou en les modifiant.
Code : Tout sélectionner
Rouge=128
Bleu=255
Vert=255
Couleur = Bleu << 16 | Vert << 8 | Rouge
Debug Hex(Couleur)
Debug Hex(RGB(Rouge,Vert,Bleu))
ou plein d'autres choses
[EDIT]
par exemple pour faire une fondue chaînée entre deux images
A = Première image
B = Seconde Image
C = Mélange des images selon le facteur de transparence 'trans'
Code : Tout sélectionner
AlphaB=255-trans
AlphaA=trans
;Valeur exacte
;CouleurC = (alphaB couleurB + (((255 - alphaB) alphaA CouleurA)/255))/255
;Plus rapide mais moins exacte
;CouleurC = (alphaB couleurB + (((255 - alphaB) alphaA CouleurA)>>8)) >>8
[EDIT2]
Bon ok , ça revient toujours à faire des divisions ou des multiplications plus vite

Publié : mer. 19/avr./2006 16:04
par KarLKoX
Les shift L et shift R sont courramment utilisés pour faire des opérations sur les bits en isolant une partie de l'opérande en déplacant de n octet la valeur (et bourrage de zéro si besoin est), associé à un opération logique binaire (and, or ...), on isole encore les bits que l'on a positionné suite à cette opération.
Ils ne servent donc pas à faire des mul ou des divs (ce ne sont pas leur objectifs) bien que l'on puisse le faire (ce qui est logique).
Publié : mer. 19/avr./2006 16:26
par comtois
il faut faire attention , c'est des décalages arithmétiques , c'est différent du décalage logique , notamment pour le décalage à droite ( qui est prévu pour la division par 2 de nombre signé ).
Publié : mer. 19/avr./2006 16:30
par KarLKoX
Les opérateurs de décalage sont obligatoirement des décalage de bits, c'est logique que ça fasse une multiplication ou une division selon le n bit que tu décales à moins que vous parlez de
cela ?
Publié : mer. 19/avr./2006 17:12
par comtois
Ce que je veux dire c'est qu'avec PB on n'a pas de décalage logique , le décalage est arithmétique à droite , il faut y penser !!
Par exemple tu prends
a , tu le décales de 3 à gauche
tu mets le résultat dans
b.
Ensuite tu décales
b de 3 à doite , tu pourrais penser retrouver la valeur de
a ? ben c'est pas le cas , parce que le bit de signe est à 1, et quand tu fais un décalage à droite avec le bit de signe à 1 , tu ne remplis pas les bits à gauche avec des zéros !
Par contre , si tu remplaces le 3 par un 2, alors tu retrouveras bien la valeur de
a, parce que le bit de signe est resté à zéro.
Avec un décalage logique, tu n'as ce problème.
Et ce décalage arithmétique est justement fait pour des division par 2 rapide
Code : Tout sélectionner
a = %00010000000000000000000000000000
Debug Bin(a)
b = a << 3
Debug Bin(b)
c = b >> 3
Debug Bin(c)
tant que le bit de signe reste à zéro , on retrouve bien
a quand on revient sur la droite
Code : Tout sélectionner
a = %00010000000000000000000000000000
Debug Bin(a)
b = a << 2
Debug Bin(b)
c = b >> 2
Debug Bin(c)
Publié : mer. 19/avr./2006 17:25
par KarLKoX
Ton exemple démontre exactement ce que j'ai dit plus haut, tu as juste omis que pour retrouver a il faut dans ce cas non pas n'utiliser que la rotation à droite mais aussi l'opérateur and :
Code : Tout sélectionner
a = %00010000000000000000000000000000
Debug Bin(a)
b = a << 3
Debug Bin(b)
c = (b >> 3) & a
Debug Bin(c)
Pourquoi ? Parce que ton "a" a été bourré de zéro à droite car ton bit de signe "1" est positionné tout à gauche, décallé de 1 à gauche un bit positionné à l'autre extremité aura toujours cet effet.
On est bien la dans une arithmetique binaire, non ?
Ceci dit, j'utilise moi aussi les shifts pour des muls/divs plus rapide, la, on est tous d'accord

Publié : mer. 19/avr./2006 17:35
par Chris
Et ça sert aussi à stocker deux valeurs dans une seule, ou à les récupérer.
Arithmétique ou logique, je sais pas, mais pratique, ça c'est sûr!
(Codes piqués dans les includes de jaPBe)
Code : Tout sélectionner
Procedure MakeLong(low.w, high.w); - Combines the high and low word to a long
ProcedureReturn low + (high<<16)
EndProcedure
Procedure LowWord(long); - Get the low word of a long
ProcedureReturn long&$FFFF
EndProcedure
Procedure HighWord(long); - Get the high word of a long
ProcedureReturn (long>>16)&$FFFF
EndProcedure
Val1 = 40
Val2 = 180
ValLong = MakeLong(Val1, Val2) : Debug ValLong
LowVal = LowWord(ValLong) : Debug LowVal
HighVal = HighWord(ValLong) : Debug HighVal
Publié : mer. 19/avr./2006 17:39
par KarLKoX
Chris m'a compris ! C'est exactement de ça que je parle

Publié : mer. 19/avr./2006 18:07
par djes
Le groupe Sanity s'est aussi servi des décalages de bits pour faire des rotations en temps réel sur Amiga 500. Me demandez pas comment

Publié : mer. 19/avr./2006 18:27
par KarLKoX
Aaahhh Jester ... un des mes zikos préférés

Publié : mer. 19/avr./2006 19:24
par comtois
Chris a écrit :Et ça sert aussi à stocker deux valeurs dans une seule, ou à les récupérer.
J'avais déjà montré ça et encore mieux , 3 valeurs dans une seule
Code : Tout sélectionner
Rouge=128
Bleu=255
Vert=255
Couleur = Bleu << 16 | Vert << 8 | Rouge
Debug Hex(Couleur)
Debug Hex(RGB(Rouge,Vert,Bleu))
Bref , on dit tous la même chose
[EDIT]
Juste pour compléter le code
Code : Tout sélectionner
Rouge=128
Vert=134
Bleu=217
Couleur = Bleu << 16 | Vert << 8 | Rouge
Debug Hex(Couleur)
Debug Hex(RGB(Rouge,Vert,Bleu))
;Efface les composantes
Rouge = 0 : Vert = 0 : Bleu = 0
;Récupère les composantes
Rouge = Couleur & $000000FF
Vert = (Couleur & $0000FF00) >> 8
Bleu = (Couleur & $00FF0000) >> 16
Debug Rouge
Debug Vert
Debug Bleu