PureBasic

Forums PureBasic
Nous sommes le Dim 21/Juil/2019 1:17

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 15 messages ] 
Auteur Message
 Sujet du message: [TUTO] Utiliser les flags
MessagePosté: Jeu 22/Déc/2016 18:50 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 29/Juin/2011 14:11
Messages: 1633
Localisation: Belgique
Bonjour à tous,

Les flags (drapeaux, en français) sont largement utilisés par les fonctions de PureBASIC, par exemple avec OpenWindow() pour centrer une fenêtre et en même temps la mettre en plein écran. Ils permettent donc de spécifier certaines propriétés en n'utilisant qu'une seule variable.
Mais comment cela fonctionne-t-il ?
  • Un flag peut avoir pour valeur 0 ou 1.
  • Un entier long (.l) est codé sur 4 octets, soit 32 bits

Nous avons donc 32 bits que nous allons pouvoir mettre à 0 ou à 1, soit 32 flags.

Pour arriver à cela, il va cependant falloir respecter quelques règles.
  • La valeur de nos constantes doit être codée sur un seul bit des 32 bits.
  • Il faudra veiller à ne pas écraser la valeur de la variable, on ne pourra donc pas utiliser l'affectation =

1) Comment sont codés nos nombres ?
Nous pensons en base 2. On démarre du bit de poids faible 0 jusqu'au bit de poids fort 31. En décimal cela donne :
Code:
#Flag_0 = 1   ; = %1 en binaire (bit 0 fixé)
#Flag_1 = 2   ; = %10 (bit 1)
#Flag_2 = 4   ; = %100 (bit 2)
#Flag_3 = 8   ; = %1000 (bit 3)
#Flag_4 = 16  ; = %10000 (bit 4)
#Flag_5 = 32  ; = %100000 (bit 5)
#Flag_6 = 64  ; = %1000000 (bit 6)
#Flag_7 = 128 ; = %10000000 (bit 7)
#Flag_8 = 256 ; = %100000000 (bit 8)
; Etc...
Un manière plus simple est de le faire en hexadécimal, $1, $2, $4, $8 par 4 octets
Code:
#Flag_0 = $0001 (bit 0 fixé)
#Flag_1 = $0002 (bit 1)
#Flag_2 = $0004 (bit 2)
#Flag_3 = $0008 (bit 3)
#Flag_4 = $0010 (bit 4)
#Flag_5 = $0020 (bit 5)
#Flag_6 = $0040 (bit 6)
#Flag_7 = $0080 (bit 7)
#Flag_8 = $0100 (bit 8)
; etc...

Ou en utilisant une énumération binaire
Code:
EnumerationBinary
    #Flags1 ; égale à 1
    #Flags2 ; égale à 2
    #Flags3 ; égale à 4
    #Flags4 ; égale à 8
    #Flags5 ; égale à 16
  EndEnumeration

2) Mettre une ou plusieurs valeurs, sans écraser les autres, par exemple pour passer vos flags à une fonction, se fait avec le OU logique (OR), opérateur "|" en PB.
Code:
mesFlags = #Flag_0 | #Flag_6 ;(= %01000001 en binaire ou $0041 en hexa ou 65 en décimal)
Le OU logique se comprend avec une table de vérité.
Exemple avec 2 valeurs :
Code:
A   B  SORTIE
0 | 0 -> 0
0 | 1 -> 1
1 | 0 -> 1
1 | 1 -> 1
Cet opérateur permet donc de ne modifier qu'un bit à la fois, sans altérer les autres.

3) Lire un flag, c'est à dire lire la valeur d'un bit spécifique.
Pour ce faire nous allons utiliser le ET logique (AND), opérateur "&" en PB. Voici sa table de vérité :
Code:
A   B  SORTIE
0 & 0 -> 0
0 & 1 -> 0
1 & 0 -> 0
1 & 1 -> 1
La sortie n'est à 1 que si les deux entrées sont à 1.
Exemple :
Code:
mesFlags = #Flag_0 | #Flag_6
If mesFlags & #Flag_6
    Debug "Le bit 6 est à 1"
EndIf
If mesFlags & #Flag_3
    Debug "Le bit 3 est à 1"
Else
    Debug "Le bit 3 est à 0"
EndIf


Et si on veux maintenant modifié l'état d'un flags et le placer à 0, comment faire?

Pour cela nous allons utiliser l'opérateur AND (&) ainsi que l'opérateur NOT (~) comme ceci
Code:
mesFlags =mesFlags &~#Flags3

L'opérateur not va inversé tous les bits
Code:
0000 0000 0010 0000 ; #Flag5 (32 en décimal)
1111 1111 1101 1111 ;devient après le NOT

Donc tous les bits à 1 seront simplement copiés avec l'opérateur ET le bit à 0 sera quant à lui mit à 0.

Exemple complet:

Code:
EnumerationBinary
    #Flags0 ; égale à 1
    #Flags1 ; égale à 2
    #Flags2 ; égale à 4
    #Flags3 ; égale à 8
     #Flags4 ; égale à 16
    #Flags5 ; égale à .32
    #Flags6 ;égale à 64
    #Flags7 ;égale à 128
EndEnumeration
Global mesFlags .l
Procedure Lit()
    For i=0 To 7
        p.l=Pow(2,i)
        If(mesFlags &p)
            Debug "Le flags "+Str(i)+" est à 1"
        Else
            Debug "Le flags "+Str(i)+" est à 0"
        EndIf
    Next
EndProcedure
; Ici j'active le Flag 1,3 et 5
mesFlags =#Flags1|#Flags3|#Flags5

; Lecture des flags pour voir le résultat
Lit()

; ici je vai placer le flag 3 à 0

mesFlags =mesFlags &~#Flags3

; Lecture des flags pour voir le résultat
Lit()


Voila, j'espère que ce petit tuto vous sera utile.

Merci à majikeyric et djes pour leurs remarques et corrections :wink:

_________________
Windows 10 64 bits PB: 5.70 ; 5.71 beta 2


Dernière édition par microdevweb le Ven 16/Juin/2017 9:04, édité 3 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [TUTO] passé jusqu'à 32 flag avec une seule variable
MessagePosté: Jeu 22/Déc/2016 23:25 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 08/Déc/2013 23:19
Messages: 602
Localisation: Hérault
... pauvre tache

_________________
Mon site dédié à ma passion pour la programmation :
http://majikeyric.free.fr


Dernière édition par majikeyric le Lun 03/Juil/2017 14:54, édité 1 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [TUTO] passé jusqu'à 32 flag avec une seule variable
MessagePosté: Ven 23/Déc/2016 0:34 
Hors ligne
Avatar de l’utilisateur

Inscription: Mar 31/Mai/2016 9:06
Messages: 2034
Citation:
passé jusqu'à 32 flag


super_variable.s ="a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9,riri,fifi,loulou,et, autant,de,flag,que,tu,veux,dans,une,seule,variable,c'est ,étonnant,non,?"

54 flag dans ma super_variable ! ;) :mrgreen:

et ici : variable.i <<< 8 octets (avec compilateur 64-bit) -9223372036854775808 à +9223372036854775807 , ça en fait des flags ...


je veux dire, les flag c'est une petite memoire, qui permet de noter un evenement dans le prg ,qui resservira plus tard ...
a partir de là , pourquoi se bloquer sur du binaire ?

dans le cadre de la programmation sur Microprocesseur ...(assembleur ) ça peut s'envisager
mais en Purebasic .... franchement, je vois pas trop l’intérêt ...

Mais merci pour le tuto .. :)

_________________
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [TUTO] passé jusqu'à 32 flag avec une seule variable
MessagePosté: Ven 23/Déc/2016 1:17 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 29/Juin/2011 14:11
Messages: 1633
Localisation: Belgique
Merci majikeyric, pour l'astuce de l’énumération binaire;

Zorro, il m'arrive souvent dans mes procédures d'utiliser des flag et les fonctions de Purebasic aussi d’ailleurs maintenant libre à chaque personne d'en voir un intérêt ou pas :wink: .

_________________
Windows 10 64 bits PB: 5.70 ; 5.71 beta 2


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [TUTO] passé jusqu'à 32 flag avec une seule variable
MessagePosté: Ven 23/Déc/2016 8:38 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 02/Oct/2011 16:17
Messages: 2153
Localisation: 50200 Coutances
Zorro a écrit:
pourquoi se bloquer sur du binaire ?

Parce que c'est la seule langue que comprend le multiprocesseur et en plus on n'est absolument pas limité au binaire, les langages de haut niveau tel que PureBasic ont été créés pour ça

Merci microdevweb, j'apprécie ton tuto.

_________________
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce GT 640 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.62, 5.70 LTS
Un homme doit être poli, mais il doit aussi être libre !


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [TUTO] passé jusqu'à 32 flag avec une seule variable
MessagePosté: Ven 23/Déc/2016 11:46 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 11/Fév/2005 17:34
Messages: 4217
Localisation: Arras, France
Je t'ai corrigé tes fautes et aussi quelques erreurs. Il y a une faute aussi dans le titre, moi je mettrais plutôt "Utiliser les flags". Tu corriges si tu veux ;)
Code:
Bonjour à tous,

Les flags (drapeaux, en français) sont largement utilisés par les fonctions de PureBASIC, par exemple avec OpenWindow() pour centrer une fenêtre et en même temps la mettre en plein écran. Ils permettent donc de spécifier certaines propriétés en n'utilisant qu'une seule variable.
Mais comment cela fonctionne-t-il ?
[list]
[*]Un flag peut avoir pour valeur 0 ou 1.
[*]Un entier long (.l) est codé sur 4 octets, soit 32 bits[/list]

Nous avons donc 32 bits que nous allons pouvoir mettre à 0 ou à 1, soit 32 flags.

Pour arriver à cela, il va cependant falloir respecter quelques règles.
[list]
[*] La valeur de nos constantes doit être codée sur un seul bit des 32 bits.
[*] Il faudra veiller à ne pas écraser la valeur de la variable, on ne pourra donc pas utiliser l'affectation =[/list]

1) Comment sont codés nos nombres ?
Nous pensons en base 2. On démarre du bit de poids faible 0 jusqu'au bit de poids fort 31. En décimal cela donne :
[code]
#Flag_0 = 1   ; = %1 en binaire (bit 0 fixé)
#Flag_1 = 2   ; = %10 (bit 1)
#Flag_2 = 4   ; = %100 (bit 2)
#Flag_3 = 8   ; = %1000 (bit 3)
#Flag_4 = 16  ; = %10000 (bit 4)
#Flag_5 = 32  ; = %100000 (bit 5)
#Flag_6 = 64  ; = %1000000 (bit 6)
#Flag_7 = 128 ; = %10000000 (bit 7)
#Flag_8 = 256 ; = %100000000 (bit 8)
; Etc...
[/code] Un manière plus simple est de le faire en hexadécimal, $1, $2, $4, $8 par 4 octets
[code]
#Flag_0 = $0001 (bit 0 fixé)
#Flag_1 = $0002 (bit 1)
#Flag_2 = $0004 (bit 2)
#Flag_3 = $0008 (bit 3)
#Flag_4 = $0010 (bit 4)
#Flag_5 = $0020 (bit 5)
#Flag_6 = $0040 (bit 6)
#Flag_7 = $0080 (bit 7)
#Flag_8 = $0100 (bit 8)
; etc...
[/code]
2) Mettre une ou plusieurs valeurs, sans écraser les autres, par exemple pour passer vos flags à une fonction, se fait avec le OU logique (OR), opérateur "|" en PB.
[code]
mesFlags = #Flag_0 | #Flag_6 ;(= %01000001 en binaire ou $0041 en hexa ou 65 en décimal)
[/code] Le OU logique se comprend avec une table de vérité.
Exemple avec 2 valeurs :
[code]A   B  SORTIE
0 | 0 -> 0
0 | 1 -> 1
1 | 0 -> 1
1 | 1 -> 1[/code] Cet opérateur permet donc de ne modifier qu'un bit à la fois, sans altérer les autres.

3) Lire un flag, c'est à dire lire la valeur d'un bit spécifique.
Pour ce faire nous allons utiliser le ET logique (AND), opérateur "&" en PB. Voici sa table de vérité :
[code]A   B  SORTIE
0 | 0 -> 0
0 | 1 -> 0
1 | 0 -> 0
1 | 1 -> 1[/code] La sortie n'est à 1 que si les deux entrées sont à 1.
Exemple :
[code]
mesFlags = #Flag_0 | #Flag_6
If mesFlags & #Flag_6
    Debug "Le bit 6 est à 1"
EndIf
If mesFlags & #Flag_3
    Debug "Le bit 3 est à 1"
Else
    Debug "Le bit 3 est à 0"
EndIf
[/code]
Voila, j'espère que ce petit tuto vous sera utile.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [TUTO] Utiliser les flags
MessagePosté: Ven 23/Déc/2016 12:39 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 29/Juin/2011 14:11
Messages: 1633
Localisation: Belgique
Merci djes
c'est vrai que c'est un peux plus compréhensible

_________________
Windows 10 64 bits PB: 5.70 ; 5.71 beta 2


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [TUTO] passé jusqu'à 32 flag avec une seule variable
MessagePosté: Ven 23/Déc/2016 14:03 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 13/Déc/2015 11:05
Messages: 649
Localisation: Allez, cherche...
Merci pour ce tuto, bien que je connaissais déja le principe :) Ca a le mérite d'éclaircir certains points, en particulier pour récupérer un flag (je me rapelle jamais comment faire :mrgreen: ) :D

@Dobro : C'est plus dans la "philosophie" de PB de passer les flags avec des constantes numériques (genre "#PB_Window_ScreenCentered | #PB_Window_SystemMenu"), plutôt que de le faire avec une chaine ou autres, et la méthode binaire est tout simplement la mieux adaptée à des flags numériques combinables ;) En plus ca fait "propre" je trouve.

_________________
"Le bug se situe entre la chaise et le clavier"
Votre expert national en bogage et segfaults.

CPU : AMD A8 Quad core - RAM 8Gb - HDD 2To
  • Windows 10 x64 - PB 5.61 x64
  • Linux Ubuntu 16.04 LTS x64 (dual boot) - PB pas encore réinstallé


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [TUTO] Utiliser les flags
MessagePosté: Ven 23/Déc/2016 14:27 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 11/Fév/2005 17:34
Messages: 4217
Localisation: Arras, France
microdevweb a écrit:
Merci djes
c'est vrai que c'est un peux plus compréhensible

De rien, le plus dur, c'est de commencer lorsqu'on se retrouve devant une "feuille blanche". Merci à toi !


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [TUTO] passé jusqu'à 32 flag avec une seule variable
MessagePosté: Ven 23/Déc/2016 15:43 
Hors ligne
Avatar de l’utilisateur

Inscription: Mar 31/Mai/2016 9:06
Messages: 2034
JohnJohnsonSHERMAN a écrit:
@Dobro : C'est plus dans la "philosophie" de PB de passer les flags avec des constantes numériques (genre "#PB_Window_ScreenCentered | #PB_Window_SystemMenu"), plutôt que de le faire avec une chaine ou autres, et la méthode binaire est tout simplement la mieux adaptée à des flags numériques combinables ;) En plus ca fait "propre" je trouve.



je ne critique pas l'optimisation de la chose :)
je dis juste que le binaire n'est pas obligatoire

la tu parles toi même de "passage de Flags" ...
en fait il s'agit de parametres , hors ce système permet de diminuer le nombre de parametres ....
mais est limité par l'information (0 ou 1 )
hors un flag peut véhiculer des informations bien plus complexes que 0 ou 1

c'est juste ça que je souligne , et que le Tuto n'aborde pas

prenons un exemple alors ...

Code:

Procedure test(Fl.s)
      If stringfield(FL,1,",")="a"
            debug "Fl=a"
      Endif
      ;
      If stringfield(FL.s,2,",")="b"
            debug "Fl=b"
      Endif
      If stringfield(FL.s,3,",")="f" ; <<< ne trouvera pas cette valeur qui pourrai allez de a à z , ou l'infini si on utilise des mots et plus de lettres
            debug "Fl=f"
      Else
            debug "pas activé le 3em parametre" ; <<< no limite !!
      Endif
      If stringfield(FL.s,4,",")="super parametre"
            debug "Fl=super parametre"
      Endif
EndProcedure
calldebugger
Flagg.s="a,b,c,super parametre"
test(Flagg.s)




on perd probablement en vitesse , mais on gagne en richesse d'informations (ce qui au final, peut nous avoir fait gagner de la vitesse ) :)

_________________
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"


Dernière édition par Zorro le Ven 23/Déc/2016 20:40, édité 1 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [TUTO] Utiliser les flags
MessagePosté: Ven 23/Déc/2016 20:02 
Hors ligne
Avatar de l’utilisateur

Inscription: Sam 23/Sep/2006 18:32
Messages: 6637
Localisation: Isere
Pour une fois, comme notre "cher man", je connaissais aussi le principe, j'en avais eu besoin dans un de mes codes et SHARDIK, de mémoire, m'avait dépanné 8)
Ce TUTO est génial car tu expliques en détail ce phénomène que je trouve vraiment MAGIQUE 8O
Merci 8)

_________________
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [TUTO] Utiliser les flags
MessagePosté: Sam 24/Déc/2016 12:29 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 29/Juin/2011 14:11
Messages: 1633
Localisation: Belgique
J'ai ajouté au tuto la manière de procéder pour placer une flags spécifique à 0.

Bonne fête à tous :wink:

_________________
Windows 10 64 bits PB: 5.70 ; 5.71 beta 2


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [TUTO] Utiliser les flags
MessagePosté: Jeu 15/Juin/2017 14:48 
Hors ligne

Inscription: Lun 26/Avr/2010 16:14
Messages: 221
Localisation: N 48° 1' 33.6" / E 0° 36' 11.3"
Bonjour,

A la lecture de ce tutoriel, je me permets juste de signaler une petite coquille au point 3 du tuto :
Citation:
3) Lire un flag, c'est à dire lire la valeur d'un bit spécifique.
Pour ce faire nous allons utiliser le ET logique (AND), opérateur "&" en PB. Voici sa table de vérité :
Code:
A   B  SORTIE
0 | 0 -> 0
0 | 1 -> 0
1 | 0 -> 0
1 | 1 -> 1

où il faudrait lire :
Code:
A   B  SORTIE
0 & 0 -> 0
0 & 1 -> 0
1 & 0 -> 0
1 & 1 -> 1



Cordialement.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [TUTO] Utiliser les flags
MessagePosté: Jeu 15/Juin/2017 15:28 
Hors ligne
Avatar de l’utilisateur

Inscription: Mar 31/Mai/2016 9:06
Messages: 2034
exacte !! :)

_________________
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [TUTO] Utiliser les flags
MessagePosté: Ven 16/Juin/2017 9:06 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 29/Juin/2011 14:11
Messages: 1633
Localisation: Belgique
@boddhi,

C'est corrigé, merci pour cette remarque pertinente.

_________________
Windows 10 64 bits PB: 5.70 ; 5.71 beta 2


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 15 messages ] 

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages

Rechercher:
Aller à:  

 


Powered by phpBB © 2008 phpBB Group | Traduction par: phpBB-fr.com
subSilver+ theme by Canver Software, sponsor Sanal Modifiye