Page 1 sur 1

Opérateurs logiques

Publié : jeu. 24/juin/2004 11:52
par Chris
Normalement, si on fait ce code:

Code : Tout sélectionner

Debug ~1 ; devrait retourner 0
Debug ~0 ; devrait retourner 1
on devrait obtenir 0 pour le premier, et 1 pour le second, puisque l'aide dit ceci:
NOT est une inversion logique (binaire)... blablabla...

RHS |Résultat
----------
0 | 1
1 | 0
ce qui est confirmé par les différents sites que j'ai visité.

Alors pourquoi ça me donne respectivement -2 et -1 ??? :?

Chris :)

Publié : jeu. 24/juin/2004 12:00
par Oliv
c'est peut-être parce-que le débbuger prend la valeur que tu lui envoi en tant que décimal et non binaire. :?:

Publié : jeu. 24/juin/2004 12:03
par Chris
Non, j'ai essayé, et c'est pareil si tu mets

Code : Tout sélectionner

debug ~%1
debug ~%0
Chris :)

Publié : jeu. 24/juin/2004 12:37
par hardy
la négation inverse les bits.
mais le résultat est interprété comme un long je pense. D'où le résultat.
(le bit de gauche, dans un long, donne le signe)

Re: Opérateurs logiques

Publié : jeu. 24/juin/2004 13:56
par Anonyme2
Chris a écrit :Normalement, si on fait ce code:

Code : Tout sélectionner

Debug ~1 ; devrait retourner 0
Debug ~0 ; devrait retourner 1
on devrait obtenir 0 pour le premier, et 1 pour le second, puisque l'aide dit ceci:
NOT est une inversion logique (binaire)... blablabla...

RHS |Résultat
----------
0 | 1
1 | 0
ce qui est confirmé par les différents sites que j'ai visité.

Alors pourquoi ça me donne respectivement -2 et -1 ??? :?

Chris :)
Qui a écrit que ~0 = 1 etc ? 8O

Hardy a raison.

Dans ton exemple c'est un long, mais le raisonnement vaut pour un word byte etc.


La doc PB dit que c'est une inversion bit à bit et il faut garder à l'esprit que tous les nombres gérés par PB (à l'heure actuelle) sont des nombres signés donc un long (32 bits) va de -2147483648 à +2147483647 , l'information sur le signe est contenue dans le nombre lui-même.

Pour ne pas se tromper, il faut passer par la représentation binaire (ou hexa pour ceux qui préfèrent) des nombres.

0 (en 32 bits) --> 00000000 00000000 00000000 00000000
et
1 (en 32 bits) --> 00000000 00000000 00000000 00000001

Le bit b0 (le + à droite) vaut 2 puissance 0 soit 1 multiplié par 1 (car le bit est à 1, si le bit avait été à 0 on multipliait par 0) puisque tout nombre élevé à la puissance 0 vaut 1.

bit b 31 --> 00000000 00000000 00000000 00000001 <-- bit B0

La solution pour stocker le signe est l'utilisation du bit b31 comme bit de signe

0 c'est un positif et 1 c'est un nombre négatif.

Donc pour trouver un nombre négatif à partir du nombre positif, on inverse bit à bit et on ajoute 1 et réciproquement

par exemple le nombre 20

0001 0100 (+20)

on inverse bit à bit
1110 1011

on ajoute 1
1110 1100 (-20) ; le dernier bit à gauche vaut 1 c'est donc un nombre négatif.

Il s'agit du complément à deux qui est utilisé pour les calcul des entiers signés.

Reprenons ton exemple

Debug ~1 ; devrait retourner 0
Debug ~0 ; devrait retourner 1


1 en 32 bit

00000000 00000000 00000000 00000001

On inverse bit à bit

11111111 11111111 11111111 11111110

on a donc bien un nombre négatif puisque le bit le plus à gauche vaut 1 et Pb ne travaille que sur les nombres signés

Ce nouveau nombre vaut -2

Pourquoi ?

Et bien on applique la règle du complément à 2 qui permet de trouver la valeur signée des nombres :

11111111 11111111 11111111 11111110

on inverse

00000000 00000000 00000000 00000001 ( = 1)

on ajoute 1

00000000 00000000 00000000 00000010 ( = 2)

donc le nombre

11111111 11111111 11111111 11111110

vaut - 2

Publié : jeu. 24/juin/2004 13:59
par Anonyme2
Heu, j'ai pas développé le calcul des nombres dans la base deux, j'espère que le calcul dans un base donnée est aquise (?????)

Sinon j'expliquerais un peu.

Publié : jeu. 24/juin/2004 14:07
par Chris
Denis a écrit :Heu, j'ai pas développé le calcul des nombres dans la base deux, j'espère que le calcul dans un base donnée est aquise (?????)

Sinon j'expliquerais un peu.
Non, pas la peine, j'ai (à peu près) compris.
Merci ;)

Chris :)

Publié : jeu. 24/juin/2004 14:11
par Dr. Dri
Oliv a écrit :c'est peut-être parce-que le débbuger prend la valeur que tu lui envoi en tant que décimal et non binaire. :?:
De toute facon même un réel est stocké de facon binaire... Y'a juste l'interprétation qui change...

Sinon si tu veux un nom bouléen chris (t'avais pas arrêté PB ? :P ), tu peux te limiter à un bit...
Par exemple avec un masque sur un bit... pour le masque on va utiliser un &...

Code : Tout sélectionner

a = 1
;on fait un non
a = (a+1)&1
;normalement on a 0
debug a
;on fait un non
a = (a+1)&1
;normalement on a 1
debug a
Reste le probleme que ta variable peut prendre la valeur 2 (tout ce qui n'est pas 0 est considéré 1 en bouléen) et la représentation d'un 2 décimal en binaire c'est %10 et %10 & %1 = %10 & %01 et ca ca donne 0...

Dans ce cas il faut trouver un moyen pour que tout nombre différent de zéro soit considéré comme un 1... La solution est dans la phrase juste avant celle là ^^

Code : Tout sélectionner

a = Random(5)

Debug a
Debug "si a différent de zéro a est égal à 1"

;on inverse
a = ((a<>0)+1)&1

Debug a
Mais ce code ne marche pas car en PB on ne peut pour le moment pas
utiliser ce genre d'expression ailleurs que dans les commandes comme if

Dri

Publié : jeu. 24/juin/2004 14:38
par fweil
En fait il y a bien un problème de représentation de nombres ...

b0.b = 0
b1.b = 1
w0.w = 0
w1.w = 1
l0.l = 0
l1.l = 1

Debug b0
Debug b1
Debug w0
Debug w1
Debug l0
Debug l1

Debug StrU(~b0, #Byte)
Debug StrU(~b1, #Byte)
Debug StrU(~w0, #Word)
Debug StrU(~w1, #Word)
Debug StrU(~l0, #Long)
Debug StrU(~l1, #Long)

Disons que cela pourrait faire l'objet d'une demande de correction de bug ou d'ajout de commandes qui ont un comportement logique différent.

Il est un fait que l'octet 255 est bien égal à -1 dans un mode binaire, et l'octet 1 égal à 1.

On ne devrait donc pas obtenir le résultat que l'on a ici.

Ce que l'on obtient est en fait le résultat d'un registre dont tous les bits sont à 1 sauf le bit 0 qui est à la valeur résultat. Moi cela m'a souvent posé des problèmes car j'utilise en principe beaucoup les équations logiques dans mon écriture de progs, mais bon j'ai aussi pris l'habitude de contourner le problème.

...

Publié : jeu. 24/juin/2004 14:40
par Chris
Dr.Dri a écrit :...chris (t'avais pas arrêté PB ?
Ben si! ... Mais ça n' a pas duré bien longtemps :lol:

Sinon, pour le reste, le truc c'était pour inverser la valeur de l'état d'une CheckBox, pour l'utiliser dans une procedure qui désactive certains gadgets.

Code : Tout sélectionner

Procedure Désactive(Flag.b)
   DisableGadget(#MonGadget,Flag)
EndProcedure

Desactive(GetGadgetState(#MaCheckBox))
La case étant cochée, (donc renvoie 1) doit activer les gadgets(DisableGadget(#MonGadget,0))

Il faut donc inverser le flag pour que 1 corresponde à 0, et inversement.

Alors je fais comme ça, et ça fonctionne/

Code : Tout sélectionner

Procedure Desactive(Flag)
  DisableGadget(#MonGadget,1!Flag)
EndProcedure

Desactive(GetGadgetState(#MaCheckBox))
Voilà voilà !!!

Chris :)

Publié : jeu. 24/juin/2004 14:56
par Dr. Dri
ah bah en binaire a xor 1 = non a, donc c'est normal que ca marche (mais ca devrai faire comme le ~, c'est à dire un inversement sur tous les bits) ce qui voudrais dire que le flag est automatiquement réduit à 1 bit.
Sinon y'avait une solution c'est a=1-a (pourtant c'est d'habitude la premiere à laquelle je pense)

Dri

Publié : jeu. 24/juin/2004 15:06
par Anonyme2
StrU est pour moi bel et bien buggé, mais peut-être que ce n'est que la fonction ~ qui est buggée


C'est le même type de problème avec le code suivant


c.b = $10
Debug c
Debug Hex(c)
Debug Hex(~c)
Debug Bin(~c)
Debug Bin(c)


On ne demande pas la conversion de byte vers long, c'est pourtant ce qui arrive lorsque l'on convertit avec ~, alors que les type byte, word long sont parfaitement définis :cry:

Là encore, c'est pour moi un bug