Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Opération bitwise

15 réponses
Avatar
Gloops
Bonjour tout le monde,

Lorsque je lis la description de l'op=E9rateur bitwise AND (&) =E0 l'adre=
sse=20
http://msdn.microsoft.com/fr-fr/library/z0zec0b2.aspx
et que je cherche =E0 la mettre en =9Cuvre, j'en viens =E0 me demander si=
elle=20
est valable sous C#.

En effet, si je tape le code suivant :

ushort usKS =3D (ushort) 0x91;
ushort usScroll =3D (ushort) 0x91;
usKS =3D usKS & usScroll;

histoire de ne retenir que le bit utile dans la premi=E8re variable si=20
elle contenait aussi autre chose (=E0 supposer qu'on l'ait initialis=E9e =

diff=E9remment, mais chaque chose en son temps),

on me jette =E0 la troisi=E8me ligne en me disant
Error 1 Cannot implicitly convert type 'int' to 'ushort'. An explicit=20
conversion exists (are you missing a cast?)=09
(CS0266)

Alors c'est quoi, le "cast" que je "miss" ?
J'ai pourtant bien l'impression d'avoir tout d=E9clar=E9 en ushort (enfin=
du=20
moins les variables que je mentionne ici), o=F9 est-ce qu'on me trouve un=
=20
int ?

J'aurais laiss=E9 tomber un vilebrequin sur la route ?

Au d=E9part c'=E9tait un UInt16 que j'avais =E0 filtrer, et puis comme l'=
aide=20
de l'op=E9rateur "&" utilisait des ushort dans son exemple j'ai fait=20
l'op=E9ration avec des ushort histoire d'essayer d'y voir clair. Vi, ben =

=E7a sera pour le prochain =E9pisode.

Je pr=E9cise que j'ai utilis=E9 la commande Build / Rebuild solution, et =
que=20
j'ai obtenu la m=EAme erreur sur la m=EAme ligne.

10 réponses

1 2
Avatar
Gloops
Gloops a écrit, le 12/11/2009 14:49 :
Bonjour tout le monde,

Lorsque je lis la description de l'opérateur bitwise AND (&) à l'ad resse
http://msdn.microsoft.com/fr-fr/library/z0zec0b2.aspx




J'ai bien fait d'afficher ça dans Firefox : la première ligne apparaî t
beaucoup plus en valeur, et du coup je réalise que je ne travaillais pa s
avec la bonne aide.

Si je ne m'abuse on sera moins hors sujet là :
http://msdn.microsoft.com/fr-fr/library/sbf85k1c(VS.80).aspx

d'autant plus que je travaille effectivement sous Visual Studio 2005
avec .Net 2.

S'agissant d'un & binaire, je vois une ligne d'exemple qui m'intéresse
bien :
Console.WriteLine("0x{0:x}", 0xf8 & 0x3f); // bitwise and

et là-dedans je vois la partie opération, 0xf8 & 0x3f

Ben ça ressemble bien à ce que j'avais fait.
Ah oui c'était avec les types de variables, qu'on m'embêtait.
Ai-je bien lu sur la page mentionnée que le & binaire est défini sur les
types intégrés, et si je me réfère là, ushort devrait bien en f aire partie :
http://msdn.microsoft.com/fr-fr/library/bfft1t3c%28VS.80%29.aspx

C'est où, que je me suis gouré ?
Avatar
Gloops
ça demeure un drôle de binse, dont je me suis sorti dans le cas pré sent
par une conversion en binaire, par Convert.ToString(nombre, 2)

Comme il s'agit de déterminer si le dernier bit est à 1 ou 0, finalem ent
ça devient assez simple.

Si quelqu'un avait une réponse un peu plus académique à ma question je
reste preneur ...
_____________________________________
Gloops a écrit, le 12/11/2009 14:49 :
Bonjour tout le monde,

Lorsque je lis la description de l'opérateur bitwise AND (&) à l'ad resse
http://msdn.microsoft.com/fr-fr/library/z0zec0b2.aspx
et que je cherche à la mettre en œuvre, j'en viens à me demander si elle
est valable sous C#.

En effet, si je tape le code suivant :

ushort usKS = (ushort) 0x91;
ushort usScroll = (ushort) 0x91;
usKS = usKS & usScroll;

histoire de ne retenir que le bit utile dans la première variable si
elle contenait aussi autre chose (à supposer qu'on l'ait initialisé e
différemment, mais chaque chose en son temps),

on me jette à la troisième ligne en me disant
Error 1 Cannot implicitly convert type 'int' to 'ushort'. An
explicit conversion exists (are you missing a cast?)
(CS0266)

Alors c'est quoi, le "cast" que je "miss" ?
J'ai pourtant bien l'impression d'avoir tout déclaré en ushort (enf in du
moins les variables que je mentionne ici), où est-ce qu'on me trouve un
int ?

J'aurais laissé tomber un vilebrequin sur la route ?

Au départ c'était un UInt16 que j'avais à filtrer, et puis comme l'aide
de l'opérateur "&" utilisait des ushort dans son exemple j'ai fait
l'opération avec des ushort histoire d'essayer d'y voir clair. Vi, be n
ça sera pour le prochain épisode.

Je précise que j'ai utilisé la commande Build / Rebuild solution, e t que
j'ai obtenu la même erreur sur la même ligne.


Avatar
Patrice
Bonjour,

Quelque chose comme ?

ushort v1 = 0xf0;
ushort v2 = 0xff;
const ushort mask=1;
Console.WriteLine(v1 & mask); // 0 le dernier bit étant 0
Console.WriteLine(v2 & mask); // 1 le dernier bit étant 1
Console.ReadKey();

Généralement on garde l'intégralité de la valeur et on teste avec un
"masque" lorsque nécessaire...

Apparemment le 1 combinant deux ushort retourne effectivement un int. Il
faudrait donc alors utiliser :

r = (ushort)(v1 & mask);

si on veut garder le résultat du "masquage".

--
Patrice
Avatar
Gloops
Patrice a écrit, le 17/11/2009 12:00 :
Bonjour,

Quelque chose comme ?

ushort v1 = 0xf0;
ushort v2 = 0xff;
const ushort mask=1;
Console.WriteLine(v1 & mask); // 0 le dernier bit étant 0
Console.WriteLine(v2 & mask); // 1 le dernier bit étant 1
Console.ReadKey();

Généralement on garde l'intégralité de la valeur et on teste av ec un
"masque" lorsque nécessaire...

Apparemment le 1 combinant deux ushort retourne effectivement un int. Il
faudrait donc alors utiliser :

r = (ushort)(v1 & mask);

si on veut garder le résultat du "masquage".

--
Patrice



Merci pour cette réponse.

Effectivement, voilà qui fonctionne.

J'avais essayé un truc du style
uKS = (ushort) (((ushort) uKS) & ((ushort) uScroll))

mais même avec ça je n'étais pas copain avec le compilateur.
Ce que je verrais bien à redire c'est que c'est lourd, mais au moins je
dis quel type de valeur je m'attends à récupérer, mais lui voit du int
là-dedans. Ah oui c'est le retour du &, tu dis ? Oui ça c'est bon à
savoir. Bon, je vais réessayer la syntaxe que je viens de citer, ça
remonte quand même à quelques jours.
Avatar
Gloops
Patrice a écrit, le 17/11/2009 12:00 :
Bonjour,

Quelque chose comme ?

ushort v1 = 0xf0;
ushort v2 = 0xff;
const ushort mask=1;
Console.WriteLine(v1 & mask); // 0 le dernier bit étant 0
Console.WriteLine(v2 & mask); // 1 le dernier bit étant 1
Console.ReadKey();

Généralement on garde l'intégralité de la valeur et on teste av ec un
"masque" lorsque nécessaire...

Apparemment le 1 combinant deux ushort retourne effectivement un int. Il
faudrait donc alors utiliser :

r = (ushort)(v1 & mask);

si on veut garder le résultat du "masquage".




ça y est, je viens de réessayer, et je ne me suis pas fait jeter.
Apparemment, le fait de savoir que le résultat d'un masquage entre
ushort donne un int a été décisif.

C'est bizarre, conceptuellement, d'ailleurs, non ?
On fait un masquage entre données codées sur 16 bits chacune, et on s e
retrouve avec une donnée sur 32 bits. Soit j'ai mal compris, soit les 1 6
bits supérieurs du résultat n'ont aucune chance de contenir autre cho se
que zéro. Serait-ce encore "by design" ?

Au fait c'est documenté où ?
Avatar
Patrice
>
C'est bizarre, conceptuellement, d'ailleurs, non ?
On fait un masquage entre données codées sur 16 bits chacune, et on se
retrouve avec une donnée sur 32 bits. Soit j'ai mal compris, soit les 16
bits supérieurs du résultat n'ont aucune chance de contenir autre chose
que zéro. Serait-ce encore "by design" ?

Au fait c'est documenté où ?




Donc un seul cast doit suffire (ou stocker le résultat sous forme d'un int).
Effectivement je suis assez d'accord et je n'ai pas trouvé le fin mot de
l'histoire (j'ai juste vu que la valeur produite était un int).

Je dirais que les valeurs produites doivent être nécessairement sur 32 bit
ou 64 bit (mon "assembleur" est un peu loin mais je pense que les opérandes
sont étendus à des valeurs 32 ou 64 bits et que le résultat produit est donc
en 32 ou 64 bits sans doute parce que le processeur ne peut pas exécuter une
instruction AND sur 16 bits sur une architecture 32 bits ?).

--
Patrice
Avatar
Gloops
Patrice a écrit, le 18/11/2009 19:22 :
Donc un seul cast doit suffire (ou stocker le résultat sous forme d'u n int).



Oui, je sais, j'ai fait fort :)
D'ailleurs, puisque je n'ai pas eu le résultat, je pense qu'au début
j'ai dû mettre seulement ceux qui n'étaient pas nécessaires. Une fo is
qu'on sait, il faut reconnaître que c'est plus facile.

Effectivement je suis assez d'accord et je n'ai pas trouvé le fin mot de
l'histoire (j'ai juste vu que la valeur produite était un int).



Ah oui avec une fonction du type typeof ...
(ou plutôt typename, si je me rappelle bien, typeof c'est pour vb ?)
Il faut avoir l'idée, de passer toutes les variables dans cette
moulinette, y compris les résultats de calculs.
Bon, à la réflexion, c'est vrai que si on me reproche de mettre ensem ble
des données de type différent ...


Je dirais que les valeurs produites doivent être nécessairement sur 32 bit
ou 64 bit (mon "assembleur" est un peu loin mais je pense que les opé randes
sont étendus à des valeurs 32 ou 64 bits et que le résultat produ it est donc
en 32 ou 64 bits sans doute parce que le processeur ne peut pas exécu ter une
instruction AND sur 16 bits sur une architecture 32 bits ?).




Ah, mon assembleur doit être encore plus loin : je n'y avais pas pensé :)


Bon, eh bien maintenant, je tâcherai de me le tenir pour dit.
Merci pour le tuyau.
Avatar
Christophe Lephay
"Patrice" <http://scribe-fr.blogspot.com/> a écrit dans le message de groupe
de discussion :
Je dirais que les valeurs produites doivent être nécessairement sur 32 bit
ou 64 bit (mon "assembleur" est un peu loin mais je pense que les
opérandes sont étendus à des valeurs 32 ou 64 bits et que le résultat
produit est donc en 32 ou 64 bits sans doute parce que le processeur ne
peut pas exécuter une instruction AND sur 16 bits sur une architecture 32
bits ?).



Le problème vient plus, amha, de l'adressage mémoire que de la capacité du
microprocesseur à faire des opération logiques sur 16 bits (ils doivent
pouvoir le faire pour rester compatibles x86, je dirais).
Avatar
Gloops
Christophe Lephay a écrit, le 19/11/2009 18:56 :
Le problème vient plus, amha, de l'adressage mémoire que de la capa cité
du microprocesseur à faire des opération logiques sur 16 bits (ils
doivent pouvoir le faire pour rester compatibles x86, je dirais).



Oh, j'imagine que le processeur veut bien faire tout ce qu'on lui dira,
du moment qu'on sait lui dire :)

http://download.intel.com/design/processor/manuals/253666.pdf
page 108

Ah oui, c'est vrai qu'il faut prendre en compte plusieurs modes. J'en ai
déjà entendu qui se moquent quand on en étudie un ...
Patrice parlait de l'environnement 32 bits. C'est la colonne Comp/Leg
qu'il faut regarder ? J'avoue que là, j'ai un flou.
Ah, en supposant que ça soit ça, r/m8 and imm8, ça a l'air de passe r, de
même que r/m16 and imm16 ...

D'après la description de l'instruction AND, à la page suivante,
l'assembleur envoie le résultat dans le premier opérande (destination ).
Donc, si on a deux opérandes de même taille et un résultat de taill e
double, j'ai comme l'impression que l'explication serait à chercher du
côté de l'implémentation, en l'occurrence sous csharp ?
Avatar
Patrice
> Donc, si on a deux opérandes de même taille et un résultat de taille
double, j'ai comme l'impression que l'explication serait à chercher du
côté de l'implémentation, en l'occurrence sous csharp ?



Ou peut-être d'abord du côté du code MSIL sous-jacent ou de la spéc du
langage ? Pour l'instant, je n'ai pas encore trouvé ou ce point particulier
est documenté...

--
Patrice
1 2