Problème de test logique

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
SPH
Messages : 4937
Inscription : mer. 09/nov./2005 9:53

Re: Problème de test logique

Message par SPH »

Code : Tout sélectionner

If Not x=0  And Not x=1
Cela pourrait il se lire : si x n'est pas egale a 0 et x n'est pas egale a 1 ?

Si oui, cela reviens a dire :

Code : Tout sélectionner

If x<>0  And x<>1
  Debug "Vrai"
Else
  Debug "Faux"
EndIf
(avec x=1)

Donc, ce code buggue :

Code : Tout sélectionner

If Not (x=0)  And Not (x=1)
  Debug "Vrai"
Else
  Debug "Faux"
EndIf
Je pense savoir pourquoi :
If Not (x=0) And Not (x=1)
se lit :
x=0
si x n'est pas egale a 0; ce qui est faux
x=1
si x n'est pas egale a 1; ce qui est faux
alors on obtient le ELSE
Debug "Faux"

!heu, tiens, il dit vrai. Bon bin je me suis planté :oops:
Dernière modification par SPH le ven. 11/févr./2011 16:19, modifié 2 fois.

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.12LTS- 64 bits
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Problème de test logique

Message par Backup »

..............
Dernière modification par Backup le sam. 01/oct./2011 10:48, modifié 1 fois.
Avatar de l’utilisateur
SPH
Messages : 4937
Inscription : mer. 09/nov./2005 9:53

Re: Problème de test logique

Message par SPH »

Je n'arrive pas a trancher......

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.12LTS- 64 bits
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Problème de test logique

Message par Ollivier »

@Kele

En corrigeant ton code que j'ai mis plus bas, le résultat est faux alors que toi tu as un résultat vrai. J'obtiens donc quelque chose de vrai avec des parenthèses alors que toi tu obtenais quelque chose de faux sans les parenthèses...

En plus il lit de droite à gauche, je crois donc quand on oublie les parenthèses, on ne trouve pas forcément le bug prévu...

Les parenthèses ne ralentissent pas l'exécution du programme mais servent à assister au compilateur.

Code : Tout sélectionner

; Condition 1 AND condition 2
If (Not (x=0 And x=1) ) And (Not (x=1 Or x=0) )
  Debug "Vrai"
Else
  Debug "Faux"
EndIf
Avatar de l’utilisateur
SPH
Messages : 4937
Inscription : mer. 09/nov./2005 9:53

Re: Problème de test logique

Message par SPH »

Moi je voudrais bien un exemple concret qui utilise tout ce bazard...

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.12LTS- 64 bits
Cls
Messages : 620
Inscription : mer. 22/juin/2005 8:51
Localisation : Nantes

Re: Problème de test logique

Message par Cls »

Code : Tout sélectionner

; Code kelebrindae n°1
If Not x=0  And Not x=1
  Debug "Vrai"
Else
  Debug "Faux"
EndIf
; Donnes => FAUX

; Equivalence compilateur n°2
If (Not x)=0  And (Not x)=1
  Debug "Vrai"
Else
  Debug "Faux"
EndIf
; Donnes => FAUX


; Code kelebrindae n°3
If Not (x=0)  And Not (x=1)
  Debug "Vrai"
Else
  Debug "Faux"
EndIf
; Donnes => VRAI

; Equivalence compilateur n°4
If (Not (x=0))  And (Not (x=1))
  Debug "Vrai"
Else
  Debug "Faux"
EndIf
; Donnes => FAUX
Je vous avoue que le code n°3 me parait tout à faite bizarre...
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

Re: Problème de test logique

Message par kelebrindae »

Merci CLS !
C'est exactement ça que j'essayais de dire: le n°3 ne me paraît pas normal.

[EDIT]
AAAAARGH !
Le n°3 ne donne un résultat différent des autres que si x = 1; si x = 0, il donne le même résultat que les autres !

Moi aussi je deviens chèvre! Bêêêh! Bêêêh!
Les idées sont le souvenir de choses qui ne se sont pas encore produites.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Problème de test logique

Message par Ollivier »

Parce que quand on écrit ceci:

Code : Tout sélectionner

If Not (x=0)  And Not (x=1)
Il compile comme ça:

Code : Tout sélectionner

If Not ((x=0)  And Not (x=1) )
Je vous l'ai dit plus haut, ça compile de droite à gauche...

Alors, un gramme plus tard, je me répète, surtout soyez généreux en parenthèse, ça ne mange pas de performance...
Cls
Messages : 620
Inscription : mer. 22/juin/2005 8:51
Localisation : Nantes

Re: Problème de test logique

Message par Cls »

Ollivier a écrit :Je vous l'ai dit plus haut, ça compile de droite à gauche...
J'avais loupé cette partie. Étonnante cette particularité ! Y'a - t - il une raison ?
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Problème de test logique

Message par Backup »

Cls a écrit :
Ollivier a écrit :Je vous l'ai dit plus haut, ça compile de droite à gauche...
J'avais loupé cette partie. Étonnante cette particularité ! Y'a - t - il une raison ?

la notation polonaise inverse ...?

les dernier elements entré son les premiers mis sur la pile ?
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Problème de test logique

Message par Ollivier »

Prce qu quand tu fourresun nimbre par ex zéero (qui sertt à rien) et que tu décrémente s ça va mieux avec un schéma
:
1) Je mets le nombre
2) Je décrémente
3) Je traite
4) Si non zéro recommence

Alor sque l'endroit::
1) Je mets 0
1) Je indrémente
2) trzite
3) Si cest la fin
4) Alors je quitte

Ce n'est plus simpler Mais KElebraillae ksa n'est pas grave
Cls
Messages : 620
Inscription : mer. 22/juin/2005 8:51
Localisation : Nantes

Re: Problème de test logique

Message par Cls »

Comme la nuit porte conseil et que la réponse d'Ollivier ne me convenait pas, j'ai poussé un peu plus loin la réflexion (pas trop non plus faut pas pousser :D).

Premier point : si ça compile de droite à gauche, ça exécute bien de gauche à droite, comme dans tous les langages. Ce code permet de le prouver :

Code : Tout sélectionner

Procedure.b test(t.s)
  Debug "Test " + t
  ProcedureReturn #True
EndProcedure

If #False And test("false") : EndIf
If #True And test("true") : EndIf
Seul "test True" est affiché donc le second test est exécuté uniquement si le premier test à gauche est VRAI.


Second point : afin de valider la portée de l'opérateur j'ai écrit ce bout de code que je pensais similaire :

Code : Tout sélectionner

x=1

; Code kelebrindae n°3
If Not (x=0)  And Not (x=1)
  Debug "Vrai"
Else
  Debug "Faux"
EndIf
; Donne => VRAI

; Code théoriquement identique
If ~(x=0)  And ~(x=1)
  Debug "Vrai"
Else
  Debug "Faux"
EndIf
; Donne => FAUX
Et là surprise => le résultat est celui attendu. 8O Les deux codes ne sont donc pas identiques. En cherchant un peu dans la doc, j'ai enfin trouvé le pourquoi du comment. Il suffisait de lire un peu :

Extrait de la doc :
Priorité des opérateurs

Niveau de priorité | Opérateurs
--------------------+---------------------
8 (haute) | ~, -
7 | <<, >>, %, !
6 | |, &
5 | *, /
4 | +, -
3 | >, >=, <, <=, =, <>
2 | Not
1 (basse) | And, Or, XOr
Notre Not n'arrive qu'en seconde position dans l'ordre des priorité. En gros, il sera évalué en dernier, juste avant les ET / OU ! Maintenant tout s'explique, ou presque car il y a, du coup, toujours un souci. Que ça compile de droite à gauche ou de gauche à droite, le Not devrait être évalué avant le And, comme précisé dans le tableau ci - dessus. Le compilateur n'a pas à ajouter de parenthèses à notre insu. Du coup je pense kelebrindae a bien remonté un bug.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Problème de test logique

Message par Ollivier »

Cls a écrit :Comme la nuit porte conseil
ça dépend ce qui précède la nuit en question...
Cls a écrit :et que la réponse d'Ollivier ne me convenait pas
Désolé pour le tas de fautes illisibles. Un sursaut de lucidité insassiable a dû me traverser l'esprit hier après une dégustation poussée pour tenter d'opérer une telle réponse. ça ne se reproduira plus. Et, bien sûr, la niaule est à consommer modérément, pour ceux que mon message ferait replonger ou dériver vers l'addiction.

Côté calcul logique, le bug (si c'est bien un bug) peut s'isoler ainsi:

Code : Tout sélectionner

x = #False

If Not x = 1 And Not x = 0
      Debug "VRAI"
Else
      Debug "FAUX"
EndIf

If Not (x = 1) And Not x = 0
      Debug "VRAI"
Else
      Debug "FAUX"
EndIf
Mais mettre toutes les parenthèses permet:
1) d'avoir une équation lisible
2) ne perd pas en performance
3) évite les bugs quand les équations sont incorporées dans les macros.

Code : Tout sélectionner

x = #False

If (Not (x = 1) ) And (Not (x = 0) )
      Debug "VRAI"
Else
      Debug "FAUX c.q.o.v."
EndIf
Après si ça ne convient pas assez en terme de fiabilité, ça peut éventuellement être mis en rapport de bug.
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Re: Problème de test logique

Message par PAPIPP »

Bonjour à tous

Voici ma petite contribution à ce débat.

Opérateur "=" est à la fois un opérateur d’affectation et un opérateur logique de TEST d’égalité
Comment le compilateur PB se tire de ce pb ?
Pas très bien à mon avis mais cela n’est pas très grave puisque nous pouvons trouver un mode de contournement
Dans l’expression A0=1 c’est l’opérateur d’affectation qui est sollicité.
Dans l’ expression If A0=1 c’est l’opérateur logique.
Mais dans l’expression A0=(Not X=0) quel est l’opérateur sollicité ?
Voyons cela de plus près et regardons les résultats ainsi que les générés ASM DE PB 4,51
remplaçons dans x les 0 par 2 et les 1 par 4 afin d'éviter les valeurs logiques 0 et 1 qui peuvent poser pb à l'interprétation
; *********************************************************************************************
; Niveau de priorité | Opérateurs
; --------------------+---------------------
; 8(haute) | ~,-
; 7 | <<,>>,%, !
; 6 | | , &
; 5 | *,/
; 4 | +,-
; 3 | >,>=,<,<=,=,<>
; 2 | Not
; 1(basse) | And, Or, XOr
******** Dans cette hiérarchie les parenthèses ont été oubliées ont peut les placer au plus haut de cette priorité
;******** l'opérateur d'affectation "=" a lui aussi été oublié il doit être au moins au niveau des parenthèses sinon plus haut

Code : Tout sélectionner

x=4
A_0=(Not x=4)=0
Debug A_0
;**************  généré ASM de A_0=(Not x=4)=0
;  x=4
; 	MOV	 dword [v_x],4
; ; A_0=(Not x=4)=0
; 	MOV	 ebx,dword [v_x]
; 	CMP	 ebx,4
; 	JNE	 No0
; 	XOR	 eax,eax
; 	JMP	 Ok0
; No0:
; 	MOV	 eax,1
; Ok0:
; 	MOV	 ebx,eax
; 	AND	 ebx,ebx
; 	MOV	 dword [v_A_0],0 ====> simple affectation de la valeur 0 a v_A_0 donc à A_0 et non résultat d'une relation logique  
; ; Debug A_0
x=4
A_1=(Not x=4)=1
Debug A_1
;**************  généré ASM de A_1=(Not x=4)=1

; ; x=4
; 	MOV	 dword [v_x],4
; ; A_1=(Not x=4)=1
; 	MOV	 ebx,dword [v_x]
; 	CMP	 ebx,4
; 	JNE	 No1
; 	XOR	 eax,eax
; 	JMP	 Ok1
; No1:
; 	MOV	 eax,1
; Ok1:
; 	MOV	 ebx,eax
; 	CMP	 ebx,1
; 	MOV	 dword [v_A_1],1   ====> simple affectation de la valeur 1 a v_A_1 donc à A_1 et non résultat d'une relation logique 
; ; Debug A_1
;**************** maintenant avec double parenthèses pour essayer que l'opérateur "=" soit un opérateur logique  
x=4
A_0=((Not x=4)=0)
Debug A_0
;**************  généré ASM de A_0=((Not x=4)=0)

; ; x=4
; 	MOV	 dword [v_x],4
; ; A_0=((Not x=4)=0)
; 	MOV	 ebx,dword [v_x]
; 	CMP	 ebx,4
; 	JNE	 No2
; 	XOR	 eax,eax
; 	JMP	 Ok2
; No2:
; 	MOV	 eax,1
; Ok2:
; 	MOV	 ebx,eax
; 	AND	 ebx,ebx
; 	MOV	 dword [v_A_0],0====> simple affectation de la valeur 0 a v_A_0 donc à A_0 et non résultat d'une relation logique 
; ; Debug A_0
; ************  Les doubles parenthèses ne suffisent pas a changer l'opérateur "=" d'affectation en opérarteur logique 


;**************** il existe des opérateurs qui ne nécessitent qu'une opérande. Il sont appelés opérateurs Monadiques.
;**************** Comme Not et un opérateur monadique de priorité  2 nous allons utiliser deux not => qui correspondent à ne rien faire
;**************** Comme "=" Opérateur logique a un niveau de priorité de 3 il faut placer deux NOT de priorité 2 qui ne font rien d'autre que
;**************** d'obtenir que "=" soit une opérateur logique 
x=4
A_0=(Not(Not(Not (x=4))=0))
Debug A_0
;**************  généré de A_0=(Not(Not(Not (x=4))=0))

; ; x=4
; 	MOV	 dword [v_x],4
; ; A_0=(Not(Not(Not (x=4))=0))
; 	MOV	 ebx,dword [v_x]
; 	CMP	 ebx,4
; 	JNE	 No2
; 	XOR	 eax,eax
; 	JMP	 Ok2
; No2:
; 	MOV	 eax,1
; Ok2:
; 	MOV	 ebx,eax
; 	AND	 ebx,ebx
; 	JNE	 No3
; 	XOR	 eax,eax
; 	JMP	 Ok3
; No3:
; 	MOV	 eax,1
; Ok3:
; 	AND	 eax,eax
; 	JE	 No4
; 	XOR	 eax,eax
; 	JMP	 Ok4
; No4:
; 	MOV	 eax,1
; Ok4:
; 	MOV	 dword [v_A_0],eax
; ; Debug A_0

;************************ POUR VERIFICATION INVERSONS LE TEST AVEC 1
x=4
A_1=(Not(Not(Not (x=4))=1))
Debug A_1
; ; x=4
; 	MOV	 dword [v_x],4
; ; A_1=(Not(Not(Not (x=4))=1))
; 	MOV	 ebx,dword [v_x]
; 	CMP	 ebx,4
; 	JNE	 No5
; 	XOR	 eax,eax
; 	JMP	 Ok5
; No5:
; 	MOV	 eax,1
; Ok5:
; 	MOV	 ebx,eax
; 	CMP	 ebx,1
; 	JNE	 No6
; 	XOR	 eax,eax
; 	JMP	 Ok6
; No6:
; 	MOV	 eax,1
; Ok6:
; 	AND	 eax,eax
; 	JE	 No7
; 	XOR	 eax,eax
; 	JMP	 Ok7
; No7:
; 	MOV	 eax,1
; Ok7:
; 	MOV	 dword [v_A_1],eax
; ; Debug A_1
; ********************** Les Résulats sont conforment à la logique CQFD  ****************************
En résumé pour que l'opérateur "=" soit un opérateur logique il faut baisser son niveau de priorité comme dans l'exemple suivant.
A_1=(Not(Not(Not (x=4))=1))

A+
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Problème de test logique

Message par Ollivier »

Après la poire, la pomme... Mais ce coup-là j'étteins l'ordi!!!
Répondre