Opérateurs logiques

Sujets variés concernant le développement en PureBasic
Avatar de l’utilisateur
Chris
Messages : 3731
Inscription : sam. 24/janv./2004 14:54
Contact :

Opérateurs logiques

Message 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 :)
Oliv
Messages : 2117
Inscription : mer. 21/janv./2004 18:39

Message 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. :?:
Avatar de l’utilisateur
Chris
Messages : 3731
Inscription : sam. 24/janv./2004 14:54
Contact :

Message par Chris »

Non, j'ai essayé, et c'est pareil si tu mets

Code : Tout sélectionner

debug ~%1
debug ~%0
Chris :)
hardy
Messages : 333
Inscription : mer. 02/juin/2004 13:19
Localisation : Tours

Message 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)
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Re: Opérateurs logiques

Message 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
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message 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.
Avatar de l’utilisateur
Chris
Messages : 3731
Inscription : sam. 24/janv./2004 14:54
Contact :

Message 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 :)
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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
fweil
Messages : 505
Inscription : dim. 16/mai/2004 17:50
Localisation : Bayonne (64)
Contact :

Message 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.

...
Mon avatar reproduit l'image de 4x1.8m présentée au 'Salon international du meuble de Paris' en janvier 2004, dans l'exposition 'Shades' réunisant 22 créateurs autour de Matt Sindall. L'original est un stratifié en 150 dpi.
Avatar de l’utilisateur
Chris
Messages : 3731
Inscription : sam. 24/janv./2004 14:54
Contact :

Message 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 :)
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message 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
Répondre