Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1
    Utente di HTML.it
    Registrato dal
    Dec 2008
    Messaggi
    324

    differenze tra & e | e && ||

    Ciao a tutti,

    apro questa discussione perchè non ho ben chiaro la differenza tra i singoli AND e OR (& e |) e i doppi AND e OR (&& e ||).

    Qualcuno mi saprebbe spiegare brevemente le differenze?


    Grazie anticipatamente

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,315
    Sono i cosiddetti operatori bitwise e short-circuit.
    Premesso che quelli singoli NON si dovrebbero usare al posto dei doppi, vediamo il perchè.

    Gli operatori singoli operano sui bit: sono operatori che servono a fare "calcoli" tra bit, non sono operatori logici. Il risultato può sembrare uguale, ma non lo è, per un semplice motivo.

    Gli operatori doppi offrono il short-circuit evaluation, mentre gli altri no. Cosa comporta? Vediamo un esempio:

    codice:
    boolean test = false;
    if (test && fireTheWorld()) {
       // The world is on fire
    }
    Questo codice effettua per prima cosa una verifica sulla condizione "test". Se questa risulta falsa, il resto dell'espressione non viene valutato, quindi non viene preso in considerazione poichè sarebbe "inutile": FALSE messo in AND con qualunque altra cosa darà sempre FALSE. Il risultato dell'espressione è già noto, non serve verificare altro.

    Nell'esempio, quindi, dato che la variabile booleana "test" è false, non viene eseguito il metodo "fireTheWorld()", non si entra nel corpo dell'isruzione if e si passa oltre.

    Questo esempio:
    codice:
    boolean test = false;
    if (test & fireTheWorld()) {
       // The world is on fire
    }
    è decisamente diverso: viene valutata prima la condizione "test" e successivamente, qualunque sia il risultato della valutazione, viene valutato anche fireTheWorld(). Con la conseguenza che, sebbene il risultato dell'espressione totale sia comunque FALSE, il metodo "fireTheWorld()" viene comunque invocato... ed il mondo va a fuoco nonostante le nostre buone intenzioni. Non si entra, comunque, nel corpo dell'if, ma il metodo viene invocato.

    Un esempio più numerico:
    codice:
    int a = 9;
    int b = 0;
    if ((b != 0) && (a / b > 1)) {   // <<-- corretto!
       // a e b non sono uguali
    }
    
    if ((b != 0) & (a / b > 1)) {   // <<-- sbagliato!
       // a e b non sono uguali
    }
    La prima if è corretta: essendo che b è uguale a 0, la seconda parte (che effettua una divisione) non viene valutata, quindi non viene eseguita.

    La seconda if è sbagliata: viene verificato che b è uguale a zero, ma ciò nonostante, la divisione successiva viene eseguita, sollevando un bell'errore di divisione per zero.

    La stessa cosa si applica all'operatore ||

    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Utente di HTML.it
    Registrato dal
    Dec 2008
    Messaggi
    324
    Originariamente inviato da LeleFT
    Sono i cosiddetti operatori bitwise e short-circuit.
    Premesso che quelli singoli NON si dovrebbero usare al posto dei doppi, vediamo il perchè.

    Gli operatori singoli operano sui bit: sono operatori che servono a fare "calcoli" tra bit, non sono operatori logici. Il risultato può sembrare uguale, ma non lo è, per un semplice motivo.

    Gli operatori doppi offrono il short-circuit evaluation, mentre gli altri no. Cosa comporta? Vediamo un esempio:

    codice:
    boolean test = false;
    if (test && fireTheWorld()) {
       // The world is on fire
    }
    Questo codice effettua per prima cosa una verifica sulla condizione "test". Se questa risulta falsa, il resto dell'espressione non viene valutato, quindi non viene preso in considerazione poichè sarebbe "inutile": FALSE messo in AND con qualunque altra cosa darà sempre FALSE. Il risultato dell'espressione è già noto, non serve verificare altro.

    Nell'esempio, quindi, dato che la variabile booleana "test" è false, non viene eseguito il metodo "fireTheWorld()", non si entra nel corpo dell'isruzione if e si passa oltre.

    Questo esempio:
    codice:
    boolean test = false;
    if (test & fireTheWorld()) {
       // The world is on fire
    }
    è decisamente diverso: viene valutata prima la condizione "test" e successivamente, qualunque sia il risultato della valutazione, viene valutato anche fireTheWorld(). Con la conseguenza che, sebbene il risultato dell'espressione totale sia comunque FALSE, il metodo "fireTheWorld()" viene comunque invocato... ed il mondo va a fuoco nonostante le nostre buone intenzioni. Non si entra, comunque, nel corpo dell'if, ma il metodo viene invocato.

    Un esempio più numerico:
    codice:
    int a = 9;
    int b = 0;
    if ((b != 0) && (a / b > 1)) {   // <<-- corretto!
       // a e b non sono uguali
    }
    
    if ((b != 0) & (a / b > 1)) {   // <<-- sbagliato!
       // a e b non sono uguali
    }
    La prima if è corretta: essendo che b è uguale a 0, la seconda parte (che effettua una divisione) non viene valutata, quindi non viene eseguita.

    La seconda if è sbagliata: viene verificato che b è uguale a zero, ma ciò nonostante, la divisione successiva viene eseguita, sollevando un bell'errore di divisione per zero.

    La stessa cosa si applica all'operatore ||

    Ciao.
    Grazie Lele sei stato esaustivo ma ti volevo chiedere ancora una cosa per OR sul suo funzionamento... nel senso che se ho:

    codice:
    int b = 0;
    int c = 1;
    
    if(b == 0 || c == 2){
        istruzione
    }
    Non dovrebbe verificare lo stesso entrambi i criteri? Mi spiego meglio se da come hai detto te con || dovrebbe verifica la prima condizione è true verifica lo stesso anche la seconda? Ma in questo caso che cosa fa dove ho una condizione a true e l'altra a false?

    codice:
    int b = 0; 
    int c = 1;  
    
    if(b == 1 || c == 2){     
       istruzione 
    }
    Invece in questo caso che la prima è già a false dovrebbe verificare anche la seconda condizione? Anche perchè a sto punto si trasformerebbe in && non credi?
    Poi mi sbaglio....

    Grazie in anticipo....

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,315
    Per l'OR vale lo stesso identico ragionamento, ma basato sul significato di OR:

    codice:
    boolean test = true;
    if (test || metodo()) {
       ...
    }
    In questo caso, il metodo non viene richiamato perchè l'espressione è già vera dopo la prima valutazione.

    codice:
    boolean test = true;
    if (test | metodo()) {
       ...
    }
    In questo caso, al contrario, viene eseguito anche il metodo, nonostante il valore dell'espressione sia già chiaro dopo la prima valutazione.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Utente di HTML.it
    Registrato dal
    Dec 2008
    Messaggi
    324
    Originariamente inviato da LeleFT
    Per l'OR vale lo stesso identico ragionamento, ma basato sul significato di OR:

    codice:
    boolean test = true;
    if (test || metodo()) {
       ...
    }
    In questo caso, il metodo non viene richiamato perchè l'espressione è già vera dopo la prima valutazione.

    codice:
    boolean test = true;
    if (test | metodo()) {
       ...
    }
    In questo caso, al contrario, viene eseguito anche il metodo, nonostante il valore dell'espressione sia già chiaro dopo la prima valutazione.


    Ciao.
    Ok grazie della spiegazione, ma a sto punto mi verrebbe da dire che non cè differenza tra il && e il ||..... o sbaglio?


    Grazie anticipatamente

  6. #6
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,315
    Originariamente inviato da manublack
    Ok grazie della spiegazione, ma a sto punto mi verrebbe da dire che non cè differenza tra il && e il ||..... o sbaglio?
    Grazie anticipatamente
    Eh?
    Cioè, secondo te un OR e un AND sono la stessa cosa?

    codice:
    boolean a = true;
    boolean b = false;
    
    System.out.println(a && b);   // false
    System.out.println(a || b);   // true
    System.out.println(a && a);   // true
    System.out.println(a || a);   // true
    System.out.println(b && b);   // false
    System.out.println(b || b);   // false
    O non ho capito io la domanda...


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  7. #7
    Utente di HTML.it
    Registrato dal
    Dec 2008
    Messaggi
    324
    Originariamente inviato da LeleFT
    Eh?
    Cioè, secondo te un OR e un AND sono la stessa cosa?

    codice:
    boolean a = true;
    boolean b = false;
    
    System.out.println(a && b);   // false
    System.out.println(a || b);   // true
    System.out.println(a && a);   // true
    System.out.println(a || a);   // true
    System.out.println(b && b);   // false
    System.out.println(b || b);   // false
    O non ho capito io la domanda...


    Ciao.

    Scusa hai ragione mi sono spiegato male, nel senso che ti faccio un esempio.... Se io scrivo:

    codice:
    boolean a = false;
    boolean b = true;
    
    System.out.println(a && b);   // false
    System.out.println(a || b);   // true
    System.out.println(a & b);   // false
    System.out.println(a | b);   // true
    Cioè con il doppio OR (||) la seconda condizione mi viene eseguita lo stesso... Come mai?

  8. #8
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,315
    Originariamente inviato da manublack
    Cioè con il doppio OR (||) la seconda condizione mi viene eseguita lo stesso... Come mai?
    Perchè, come detto, la valutazione si ferma non appena il risultato può essere già garantito. Se il primo termine è false non posso sapere se più avanti ne troverò uno a true. Al contrario, se il primo è già true, non serve che vada avanti a valutare tutti gli altri. O meglio... si ferma al primo true che incontra. Prova questo esempio:

    codice:
    private static boolean valuta(int i, boolean valore) {
       System.out.println("Valuto " + i + ": " + valore);
       return valore;
    }
    
    public static void main(String[] args) {
       System.out.println("Short-circuit OR ( || ): ");
       System.out.println(valuta(0, false) || valuta(1, true) || valuta(2, false) || valuta(3, false));
    
       System.out.println("\n\n");
    
       System.out.println("Bitwise OR ( | ): ");
       System.out.println(valuta(0, false) | valuta(1, true) | valuta(2, false) | valuta(3, false));
    }
    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  9. #9
    Utente di HTML.it
    Registrato dal
    Dec 2008
    Messaggi
    324
    Originariamente inviato da LeleFT
    Perchè, come detto, la valutazione si ferma non appena il risultato può essere già garantito. Se il primo termine è false non posso sapere se più avanti ne troverò uno a true. Al contrario, se il primo è già true, non serve che vada avanti a valutare tutti gli altri. O meglio... si ferma al primo true che incontra. Prova questo esempio:

    codice:
    private static boolean valuta(int i, boolean valore) {
       System.out.println("Valuto " + i + ": " + valore);
       return valore;
    }
    
    public static void main(String[] args) {
       System.out.println("Short-circuit OR ( || ): ");
       System.out.println(valuta(0, false) || valuta(1, true) || valuta(2, false) || valuta(3, false));
    
       System.out.println("\n\n");
    
       System.out.println("Bitwise OR ( | ): ");
       System.out.println(valuta(0, false) | valuta(1, true) | valuta(2, false) | valuta(3, false));
    }
    Ciao.

    Provato.....

    Il risultato dell'esempio che mi hai dato è:

    Short-circuit OR ( || ):
    Valuto 0: false
    Valuto 1: true
    true

    Bitwise OR ( | ):
    Valuto 0: false
    Valuto 1: true
    Valuto 2: false
    Valuto 3: false
    true


    Alla Fine nel Short-circuit è stato eseguito anche la seconda condizione anche se nel primo caso è false......

  10. #10
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,315
    Originariamente inviato da manublack
    Alla Fine nel Short-circuit è stato eseguito anche la seconda condizione anche se nel primo caso è false......
    Ed è corretto. La valutazione di un OR non può fermarsi al primo false, può fermarsi solo al primo TRUE.

    Mi sa che ti mancano delle nozioni fondamentali sulle tabelle di verità relative agli OR e agli AND:

    Un'espressione tra operandi in AND è FALSE se almeno uno degli operandi è FALSE.
    Ergo, con un AND mi fermo al primo FALSE che trovo.
    codice:
    op1 AND op2 AND op3 AND ... AND opN
    E' false se almeno uno dei vari opI è FALSE

    Un'espressione tra operandi in OR è TRUE se almeno uno degli operandi è TRUE.
    Ergo, con un OR mi fermo al primo TRUE che trovo.
    codice:
    op1 OR op2 OR op3 OR ... OR opN
    E' true se almeno uno dei vari opI è TRUE


    Ti è chiaro questo concetto?


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.