Page 1 sur 2

Tuto - Exercice pour esprits tordus

Posté : 19 oct. 2017, 22:19
par itasoft
cliquer dessus pour agrandir
tordu.JPG
-
-
Une des solutions aussi tordue que la question

IF (DINT0 AND REAL_TO_DINT(EXPT_REAL_INT(2.0, INT0)))>0 then
W0:=0;
end_if;

Re: Tuto - Exercice pour esprits tordus

Posté : 20 oct. 2017, 10:32
par philou77
Salut Itasoft,

Pas mieux, ta solution est simple .

:-)

Re: Tuto - Exercice pour esprits tordus

Posté : 22 oct. 2017, 13:11
par steph68
au lieu d'utiliser une fonction mathématique (EXPT), utilises plutot une fonction logique (SHL)

var AND SHL(1, rang)

reste à accorder les types (SHL_DINT) ...

pour info, les réels 32 bits n'ont que 23 bits de mantisse.
tu risques de te retrouver avec 2^24 par ex = 16777215.99999 et le REAL_TO_DINT fait une troncation (donc 16777215 au lieu de 16777216 :mrgreen: )

sans compter l'explosion nucléaire qui se produira si rang = 99 par ex

@+

EDIT: à vérifier sur les softs Schneider, mais en théorie tu devrais pouvoir écrire IF DINT0 & 2**INT0 THEN ...
l'opérateur ** correspond à EXPT et est normalisé (voir norme IEC 61131-3)
operators.jpg

Re: Tuto - Exercice pour esprits tordus

Posté : 22 oct. 2017, 15:00
par itasoft
slts,
rien ne sert de penser, il faut réfléchir avant ,
il faut mettre ton exemple en Unity et on va tester tout ça

Re: Tuto - Exercice pour esprits tordus

Posté : 22 oct. 2017, 15:45
par steph68
pas envie de démarrer Unity ... il est sur un autre PC que celui que j'utilise maintenant ...

mais vu ta réponse, c'est que tu as déjà essayé auparavant et qu'il doit y avoir une limitation du genre que le nombre de décalages doit être une valeur constante, ou un autre problème de "typage" ... :mrgreen:

ceci dit Unity n'est pas une référence non plus

maintenant la solution simple et précise est le décalage logique et le masquage
si le soft ne le permet pas c'est qu'il est programmé avec les pieds (donc il faut changer l'équipe d'informaticien chez Schneider)

tu fais une manipulation sur des champs de bits, donc la variable devrait être de type DWORD plutot que DINT ...
mais il me semble qu'Unity accepte les opérations logiques sur les INT (et peut-être les DINT également, à vérifier).

SHR(DWORD0, INT0) AND 1 ou DWORD0 AND SHL(1, INT0) c'est pareil ...

@+

Re: Tuto - Exercice pour esprits tordus

Posté : 22 oct. 2017, 16:19
par steph68
bon je viens d'essayer sur Unity ... c'est vrai que c'est lourd ce controle de typage

une version testée:

Code : Tout sélectionner

IF ((SHR(DINT_TO_DWORD(valeur), INT_TO_UINT(rang)) AND 1) <> 0) THEN
...
END_IF;
c'est plus simple de déclarer valeur comme DWORD et rang comme UINT

sinon cette version est également acceptée:

Code : Tout sélectionner

IF ((valeur AND REAL_TO_DINT(2.0 ** rang)) <> 0) THEN
...
END_IF
sur Codesys (SoMachine dans la version Codesys), c'est moins chiant car ceci est accepté sans problème:

Code : Tout sélectionner

IF ((SHR(valeur, rang) AND 1) <> 0) THEN
...
END_IF
avec un petit avertissement (pas une erreur) qui dit que rang est convertit implicitement en UINT
donc Unity est programmé avec les pieds 8-)

@+

Re: Tuto - Exercice pour esprits tordus

Posté : 22 oct. 2017, 16:32
par itasoft
slts,
comme c'est précisé sur mon post, l'exemple ne concerne que Unity seulement.
alors tu met ton exemple sur Unity que l'on puisse le tester et c'est tout.

Re: Tuto - Exercice pour esprits tordus

Posté : 22 oct. 2017, 16:45
par steph68
relax @itasoft c'est dimanche ...
relis plus haut, tu as loupé un post entretemps ...

@+

Re: Tuto - Exercice pour esprits tordus

Posté : 22 oct. 2017, 18:58
par itasoft
Slts,
Ok, vu et testé, effectivement j’avais pas vu que le décalage logique d’une position contenue dans une variable
Ne marche que sur le type WORD et UINT , de la baise.
Ok dans ce cas ta solution est plus logique binaire.
Conclusion , rien ne sert de s’énerver il faut tester avant,
Lol

Re: Tuto - Exercice pour esprits tordus

Posté : 22 oct. 2017, 19:18
par steph68
il y a SHL_DINT dans la bibliothèque obsolète, qui prend un DINT et un INT en param

testé avec

Code : Tout sélectionner

IF ((valeur AND SHL_DINT(1, rang)) <> 0) THEN
...
END_IF;
mais là on chipotte :mrgreen:
demain on va trouver une autre façon de l'écrire :D

@+