Connaître le rang d'un bit à 1 dans un mot.
- Béryl
- Mi homme - Mi automate

- Messages : 1953
- Enregistré le : 20 oct. 2015, 12:00
- Localisation : localhost
Connaître le rang d'un bit à 1 dans un mot.
Amis cyborgs, bonjour !
Je me prends la tête sur une routine que j'arrive pas à pondre comme je veux en list sur Step 7 (CPU 312).
J'ai un mot dont je fais une rotation (le bit 15 est renvoyé dans le 0) chaque seconde.
Un seul bit est actif, le mot a donc toujours une valeur de puissance de 2.
Je voudrais connaître le rang du bit actif à un moment donné.
Ex : MW30=8, c'est donc le 4ème bit qui est à 1, la routine me renvoie la valeur 4.
Je pourrais faire une boucle avec un compteur, vous me direz, mais je suis sûr qu'il y a une méthode plus pratique/courte/facile.
Z'en pensez quoi ?
Je me prends la tête sur une routine que j'arrive pas à pondre comme je veux en list sur Step 7 (CPU 312).
J'ai un mot dont je fais une rotation (le bit 15 est renvoyé dans le 0) chaque seconde.
Un seul bit est actif, le mot a donc toujours une valeur de puissance de 2.
Je voudrais connaître le rang du bit actif à un moment donné.
Ex : MW30=8, c'est donc le 4ème bit qui est à 1, la routine me renvoie la valeur 4.
Je pourrais faire une boucle avec un compteur, vous me direz, mais je suis sûr qu'il y a une méthode plus pratique/courte/facile.
Z'en pensez quoi ?
- itasoft
- Mi homme - Mi automate

- Messages : 7803
- Enregistré le : 20 oct. 2015, 10:15
- Localisation : Lyon
- Contact :
Re: Connaître le rang d'un bit à 1 dans un mot.
direct sans boucle: n=log(W) / log(2)
--------
Exemple : %MW0=n° du seul bit à 1 dans %MW1
%MW0:=REAL_TO_INT(LOG(INT_TO_REAL(%MW1))/LOG(2.0));
-------avec boucle------
%MW0:=-1;
WHILE %MW1<>0 DO
%MW0:=%MW0+1;
%MW1:=SHR(%MW1,1);
END_WHILE;
--------
Exemple : %MW0=n° du seul bit à 1 dans %MW1
%MW0:=REAL_TO_INT(LOG(INT_TO_REAL(%MW1))/LOG(2.0));
-------avec boucle------
%MW0:=-1;
WHILE %MW1<>0 DO
%MW0:=%MW0+1;
%MW1:=SHR(%MW1,1);
END_WHILE;
Modifié en dernier par itasoft le 23 août 2025, 08:25, modifié 3 fois.
Automaticien privé (de tout)
itasoft@free.fr
itasoft@free.fr
- Béryl
- Mi homme - Mi automate

- Messages : 1953
- Enregistré le : 20 oct. 2015, 12:00
- Localisation : localhost
Re: Connaître le rang d'un bit à 1 dans un mot.
Merci Ita !
Ça s'annonce coton en list, mais ça se joue !
Ça s'annonce coton en list, mais ça se joue !
-
MiGaNuTs
- Mi homme - Mi automate

- Messages : 1572
- Enregistré le : 12 nov. 2015, 21:02
- Localisation : 45 - Loiret
- Contact :
Re: Connaître le rang d'un bit à 1 dans un mot.
Sinon une bonne vieille boucle de 0 a 15 avec des divisions par 2 ou des décalages a droite c'est simple, (re)lisible et ca marche.
Se faire des noeuds au cerveau pour le plaisir c'est rigolo 5 minutes, mais qd il faut revenir dessus x années plus tard parfois on regrete.
Se faire des noeuds au cerveau pour le plaisir c'est rigolo 5 minutes, mais qd il faut revenir dessus x années plus tard parfois on regrete.
- JC87
- Mi homme - Mi automate

- Messages : 2230
- Enregistré le : 20 oct. 2015, 13:00
- Localisation : Nouvelle Aquitaine
Re: Connaître le rang d'un bit à 1 dans un mot.
Faut le faire en SCL, ça devrait pouvoir s'écrire quasiment tel quel.
JC
"On veut faire du zéro défaut mais on a zéro bonhomme et zéro budget, et bien à la fin on a zéro résultat..."
Re: Connaître le rang d'un bit à 1 dans un mot.
Salut,
Soit un FC que tu nommes par exemple FFS_WORD (Find First Set sur un WORD) avec en entrée une variable "Bits" de type WORD, une variable temporaire "x" de type WORD également, et le résultat (dans la rubrique RETURN de l'interface) "RET_VAL" de type INT :
Je n'ai pas testé mais cela devrait fonctionner ; tiens moi au courant.
Plus d'info sur le sujet ici : https://en.wikipedia.org/wiki/Find_first_set
@+
Soit un FC que tu nommes par exemple FFS_WORD (Find First Set sur un WORD) avec en entrée une variable "Bits" de type WORD, une variable temporaire "x" de type WORD également, et le résultat (dans la rubrique RETURN de l'interface) "RET_VAL" de type INT :
Code : Tout sélectionner
L #Bits
PUSH
NEGI
UW // isolation du premier bit à 1 (= Bits AND -Bits)
L -1
SPZ L4 // si pas de bit alors résultat = -1
POP
T #x
UW W#16#AAAA
L 0
SPZ L1
+ 1
L1: L #x
UW W#16#CCCC
POP
SPZ L2
+ 2
L2: L #x
UW W#16#F0F0
POP
SPZ L3
+ 4
L3: L #x
UW W#16#FF00
POP
SPZ L4
+ 8
L4: T #RET_VAL
SET
SAVE // pour que la broche ENO du bloc soit passante
Plus d'info sur le sujet ici : https://en.wikipedia.org/wiki/Find_first_set
@+
- Béryl
- Mi homme - Mi automate

- Messages : 1953
- Enregistré le : 20 oct. 2015, 12:00
- Localisation : localhost
Re: Connaître le rang d'un bit à 1 dans un mot.
Merci Steph68, mais...
Je vais essayer ton code et même le garder précieusement sous le coude s'il tourne bien.
Par contre, je ne vais pas m'en servir dans mon programme actuel, parce que ma petite routine est déjà bien assez compliquée pour ce qu'elle fait et je m'efforce de bien la commenter pour que le ou la prochain(e) qui y reviendra dans quelques années ne perde pas autant de neurones que moi en la codant
Je vais essayer ton code et même le garder précieusement sous le coude s'il tourne bien.
Par contre, je ne vais pas m'en servir dans mon programme actuel, parce que ma petite routine est déjà bien assez compliquée pour ce qu'elle fait et je m'efforce de bien la commenter pour que le ou la prochain(e) qui y reviendra dans quelques années ne perde pas autant de neurones que moi en la codant
Re: Connaître le rang d'un bit à 1 dans un mot.
La simplification est peut-être de gérer un compteur de 0 à 15 qui reboucle pour ensuite positionner un bit en fonction de ce compteur plutôt que de le faire à l'envers... mais ne connaissant pas le contexte...
ou bien
bit à partir d'un rang :
tout ceci s'écrit très bien en LADDER et se passe de commentaires
@+
Code : Tout sélectionner
compteur := (compteur + 1) AND 15Code : Tout sélectionner
compteur := (compteur + 1) MOD 16Code : Tout sélectionner
bit = SHL(1, rang);@+
Re: Connaître le rang d'un bit à 1 dans un mot.
pour compléter, ce que j'ai écris est plus ou moins cet algorithme (source https://graphics.stanford.edu/~seander/ ... htParallel)
Count the consecutive zero bits (trailing) on the right in parallel
sauf que je l'ai fais dans l'autre sens.
une fois que tu as compris le concept, c'est facile à mettre en oeuvre.
@+
Count the consecutive zero bits (trailing) on the right in parallel
Code : Tout sélectionner
unsigned int v; // 32-bit word input to count zero bits on right
unsigned int c = 32; // c will be the number of zero bits on the right
v &= -signed(v);
if (v) c--;
if (v & 0x0000FFFF) c -= 16;
if (v & 0x00FF00FF) c -= 8;
if (v & 0x0F0F0F0F) c -= 4;
if (v & 0x33333333) c -= 2;
if (v & 0x55555555) c -= 1;une fois que tu as compris le concept, c'est facile à mettre en oeuvre.
@+
