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 ! :roll:

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 :D

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