IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

OR ou XOR entre 2 int.


Sujet :

C#

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 5
    Par défaut OR ou XOR entre 2 int.
    Bonjour,

    Je cherche à faire l'opération suivante en c# :

    (x OR (2^n)) = x par exemple (66 OR (2^6))=66.

    Mais le OR (||) en c# ne fonctionne qu'entre 2 valeurs boolean.

    Comment puis-je réaliser ce type d'opération (qui fonctionne très bien en VB).

    Merci pour votre aide

  2. #2
    Membre averti
    Inscrit en
    Juillet 2009
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 47
    Par défaut
    Citation Envoyé par pilote35 Voir le message
    (x OR (2^n)) = x par exemple (66 OR (2^6))=66.
    c est un test pour savoir si 66 == 66 ou 2^6 == 66 ?
    ou si (66 ou logique (2^6) == 66 ?

  3. #3
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Essaye avec l'opérateur "|" qui est à la fois un opérateur booléen et un opérateur bitwise.
    L'opérateur "||" est le "OU" booléen optimisé qui autorise à ne pas évaluer la totalité d'un prédicat.

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 5
    Par défaut
    Citation Envoyé par gouroupasdebol Voir le message
    c est un test pour savoir si 66 == 66 ou 2^6 == 66 ?
    ou si (66 ou logique (2^6) == 66 ?
    c'est pour savoir si (66 ou logique (2^6)) == 66

    Le but est d'appliquer un masque sur un integer. Cela permet me permet à partir d'une seule valeur de checked différentes checkboxes dans une windows.form.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 5
    Par défaut
    Citation Envoyé par seriousme Voir le message
    Essaye avec l'opérateur "|" qui est à la fois un opérateur booléen et un opérateur bitwise.
    L'opérateur "||" est le "OU" booléen optimisé qui autorise à ne pas évaluer la totalité d'un prédicat.
    J'ai essayé l'opérateur | mais il réalise une simple addition sur 2 entiers et non un OU logique bit à bit.

  6. #6
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Normal :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        2 : 0010
     OU 4 : 0100
     =  6 : 0110
    Et oui, un OU bit à bit ca donne le même résultat qu'une addition dans certains cas.
    Mais pas dans d'autres :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        3 : 0011
     OU 2 : 0010
     =  3 : 0011
    Le | est un OU binaire (bitwise, bit à bit), alors que le || est un OU logique (retourne VRAI si la partie gauche est VRAI ou que la partie droite est VRAI, ces deux parties peuvent être des expressions, un nombre est considéré vrai s'il est différent de 0).

    Edit : Ah oui, autre chose :
    66 | (2^6) == 66; // Vrai tant que 2^6 inférieur ou égale à 66
    66 == 66 || 2^6 == 66; // Toujours vrai puisque 66 = 66.

    Les masques binaires seront plutot à utiliser comme ca :
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
     
    public class MaForm : Form
    {
    int _checked = 0;
     
    const int CASE_1 = 1;
    const int CASE_2 = 2;
    const int CASE_3 = 4;
    const int CASE_4 = 8;
    ....
     
    public int Check
    {
    get { return _checked;}
    set { _checked = value; DoCheck();}
    }
     
    private void DoCheck()
    {
    MaCheckBox1.Checked = (_checked & CASE_1) != 0;
    MaCheckBox2.Checked = (_checked & CASE_2) != 0;
    MaCheckBox3.Checked = (_checked & CASE_3) != 0;
    MaCheckBox4.Checked = (_checked & CASE_4) != 0;
    }
     
    private void MaCheckBox1_CheckedChanged(object sender, EventArgs e)
    {
    if(MaCheckBox1.Checked)
    _checked |= CASE_1;
    else
    _checked &= !CASE_1;
    }
     
    private void MaCheckBox2_CheckedChanged(object sender, EventArgs e)
    {
    if(MaCheckBox2.Checked)
    _checked |= CASE_2;
    else
    _checked &= !CASE_2;
    }
     
    private void MaCheckBox3_CheckedChanged(object sender, EventArgs e)
    {
    if(MaCheckBox3.Checked)
    _checked |= CASE_3;
    else
    _checked &= !CASE_3;
    }
     
    private void MaCheckBox4_CheckedChanged(object sender, EventArgs e)
    {
    if(MaCheckBox4.Checked)
    _checked |= CASE_4;
    else
    _checked &= !CASE_4;
    }

    L'utilisation d'un enum avec l'attribut Flags peut être très utile aussi.

  7. #7
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par ctxnop Voir le message
    Le | est un OU binaire (bitwise, bit à bit),
    Pas uniquement : si appliqué à des booléen, c''est un ou logique non optimisé, c'est à dire avec évaluation des deux termes, même si le premier est vrai. C'est spécifique C# (ça n'existe pas dans les autres langages utilisant une syntaxe similaire).

    Cette règle syntaxique (la version "binaire" des opérateurs logiques appliqués à des booléen est un opérateur logique non optimisé) est vraie pour tous les opérateurs logiques en C# (&, |, ^)

    Par exemple, essaye :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
     
    bool func1()
    {
    Console.WriteLine("Call Func1");
    return true;
    }
    bool func2()
    {
    Console.WriteLine("Call Func2");
    return true;
    }
     
    void test()
    {
         Console.WriteLine("Single |");
         bool a = func1() | func2();
         Console.WriteLine("Double |");
         bool b = func1() || func2();
    }
    Citation Envoyé par ctxnop Voir le message
    L'utilisation d'un enum avec l'attribut Flags peut être très utile aussi.
    L'attribut Flag n'a absolument aucune influence sur le comportement de l'enum en terme d'évaluation, et a uiquement une influence sur le ToString et sur la visibilité dans le Debugger (quand on met l'attribut Flag, il "étend" l'affichage aux champs séparés).

  8. #8
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Citation Envoyé par Bluedeep Voir le message
    Pas uniquement : si appliqué à des booléen, c''est un ou logique non optimisé, c'est à dire avec évaluation des deux termes, même si le premier est vrai. C'est spécifique C# (ça n'existe pas dans les autres langages utilisant une syntaxe similaire).

    Par exemple, essaye :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
     
    bool func1()
    {
    Console.WriteLine("Call Func1");
    return true;
    }
    bool func2()
    {
    Console.WriteLine("Call Func2");
    return true;
    }
     
    void test()
    {
         bool a = func1() | func2();
         bool b = func1() || func2();
    }
    Ce n'est pas spécifique à C#, c'est tout à fait normal. C'est toi qui interprète ca comme un OU logique non optimisé, mais non, c'est bien un OU binaire, et pour faire un OU binaire il est impératif de connaitre la valeur des deux membre et donc d'évaluer les deux expression qui le constituent. Les opérateurs binaire ne sont en aucun cas des conditions, ce sont des opérations au même titre que l'addition ou la soustraction.

    Et si, l'attribut flag à une influence, il sert justement à permettre la superposition de valeurs.

    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    enum A
    {
        A1 = 1,
        A2 = 2,
        A3 = 4
    }
     
    A _un_enum = A.A1; // Ca passe, normal
    _un_enum = A.A1 | A.A2; // Compile pas car le résultat ne fait pas partie de l'enum
     
    [Flag()]
    enum B
    {
        B1 = 1,
        B2 = 2,
        B3 = 4
    }
     
    B _un_autre_enum = B.B1; // Ca passe, normal
    _un_autre_enum = B.B1 | B.B2; // Ca passe aussi

  9. #9
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    C'est spécifique C# (ça n'existe pas dans les autres langages utilisant une syntaxe similaire).
    Non ce n'est pas une "exclu" C#, c'est à priori juste une reprise de la sémantique du langage Java.
    Et ça devait déjà exister avant Java.

  10. #10
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par ctxnop Voir le message
    Ce n'est pas spécifique à C#, c'est tout à fait normal. C'est toi qui interprète ca
    Je cite MSDN : For bool operands, | computes the logical OR of its operands

    Et si, l'attribut flag à une influence, il sert justement à permettre la superposition de valeurs.
    Ben non. Ce que tu affirmes ne pas compiler compile très bien.
    Flags (et pas Flag) n'a aucune influence sur la compilation/exécution en dehors de la méthode 'ToString()'

  11. #11
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par seriousme Voir le message
    Non ce n'est pas une "exclu" C#, c'est à priori juste une reprise de la sémantique du langage Java.
    Et ça devait déjà exister avant Java.
    Au temps pour moi alors; mais comme en C/C++ la notion de type spécifique booléen n'existe pas, j'ai extrapolé.

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 5
    Par défaut
    Citation Envoyé par ctxnop Voir le message
    Normal :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        2 : 0010
     OU 4 : 0100
     =  6 : 0110
    Et oui, un OU bit à bit ca donne le même résultat qu'une addition dans certains cas.
    Mais pas dans d'autres :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        3 : 0011
     OU 2 : 0010
     =  3 : 0011
    Le | est un OU binaire (bitwise, bit à bit), alors que le || est un OU logique (retourne VRAI si la partie gauche est VRAI ou que la partie droite est VRAI, ces deux parties peuvent être des expressions, un nombre est considéré vrai s'il est différent de 0).

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 5
    Par défaut
    OK merci à vous tous j'ai résolu mon problème.

  14. #14
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Citation Envoyé par Bluedeep Voir le message
    Je cite MSDN : For bool operands, | computes the logical OR of its operands

    Ben non. Ce que tu affirmes ne pas compiler compile très bien.
    Flags (et pas Flag) n'a aucune influence sur la compilation/exécution en dehors de la méthode 'ToString()'
    Après test, effactivement ca compile. Méa culpa donc (j'étais poourtant certain d'avoir eu le tour avec un enum où l'attribut flags avait résolut le problème).

    Concernant la citation MSDN, t'en oublie un petit bout :
    Citation Envoyé par MSDN
    For integral types, | computes the bitwise OR of its operands. For bool operands, | computes the logical OR of its operands; that is, the result is false if and only if both its operands are false.
    La raison est simple, on ne peux faire du bit à bit que sur des nombres entiers or, en managé, le bool n'est pas un nombre entier. En réalité, physiquement, on peux le faire sur n'importe quoi mais le résultat sera du grand n'importe quoi, voir fera tout planter. En C, le bool n'existe pas, on part du principe que tout ce qui est différent de 0 est vrai et donc 0 = faux. Le bool à tout de même été introduit en C par le C99 qui à apporté le fichier stdbool.h, mais bon, ca ne fait que continuer de considérer le bool comme un nombre entier auquel on peux donc appliquer des opérateurs binaires.

    C'est donc parce que le bool n'est pas traité comme un nombre entier en C#, Java#, VB.Net, etc..., que le cas est traité comme particulier, afin de conserver le comportement présent en assembleur, C, C++, et tout autre langage système. C'est la base de l'électronique numérique.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 28/12/2013, 13h01
  2. XOR entre 2 tableaux
    Par Umlist dans le forum C
    Réponses: 11
    Dernier message: 28/06/2012, 22h59
  3. [OpenSSL] Faire un xor entre deux BN
    Par babbab dans le forum Bibliothèques
    Réponses: 0
    Dernier message: 08/01/2011, 15h38
  4. Différences entre 2 int[] arrays ?
    Par Danny Blue dans le forum ASP.NET
    Réponses: 1
    Dernier message: 30/11/2007, 23h27
  5. conversion (cast) entre IntPtr int[]
    Par glebourg dans le forum C#
    Réponses: 2
    Dernier message: 29/03/2007, 10h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo