Newsgroup: it.comp.java
Titolo: !!!

    Salve a tutti.
mi rivolgo a qualcuno di voi sperando di riuscire a sciogliere 2 dei miei
dubbi.
che differenza c'è tra | e ||???
che differenza c'è tra & e &&???
nonostante i mie sforzi non sono riuscito a interpretare il concetto.

,

| e & sono operatori *numerici* che agiscono sui bit degli operandi
(fornendone rispettivamente l'or e l'and bit-a-bit).
Ad esempio (usando 8 bit) 3 (cioe' 00000011) & 2 (cioe' 00000010) fa 2.
|| e && sono invece *booleani*, e forniscono l'or e l'and logici dei
boolean dati come operandi: ad esempio, "true && false" vale "false".
Tutto qui. :)
--
God is Real, unless declared Integer
Sent via Deja.com 
http://www.deja.com/
Share what you know. Learn what you don't.

 nonostante i mie sforzi non sono riuscito a interpretare il concetto.
Spero tu non abbia problemi con l'algebra di boole,
altrimenti ti
consiglio di vedere prima le tabelle degli or e degli
and.
Comunque, quelli più "corti" finiscono di interpretare
la condizione,
ovvero valutano la condizione fino in fondo (strict).
Quelli "lunghi"
invece evitano di valutare espressioni ormai inutili
quando il valore è
ormai deciso. Ciò porta a differenze di comportamento
in casi
particolari.
Esempio 1:
nell'espressione "if (a || c)" c non viene valutato se
a è già vero,
poichè non influisce sul risultato finale, che sarà
comunque vero.
Usando l'operatore | invece c verrebbe valutato
ugualmente. Se la
valutazione non ha "side effects" (effetti
collaterali), come in questo
caso,  non cambia molto, ma se ne ha può avere un
senso.
Esempio 2:
if (a || test.addValue(10))
supponendo che il metodo addValue restituisca true se
è stato aggiunto
il valore correttamente, o false se per qualche motivo
non è stato
possibile, si comporterebbe diversamente con
l'operatore |; infatti in
questo caso addValue verrebbe eseguito comunque,
mentre con || non
verrebbe eseguito nel caso a fosse già true, in quanto
inutile per la
valutazione del risultato finale (che è comunque
true). Ovviamente però
il valore non verrebbe aggiunto, dunque ci sono delle
differenze. E'
comunque una pratica sconsigliabile scrivere codice
come quello
dell'esempio 2, poichè può portare ad errori difficili
da interpretare e
trovare. E' sempre meglio assegnare il risultato di un
metodo del genere
ad una variabile booleana, ed effettuare la condizione
successivamente.
Considera infatti che, alla luce di quanto detto,
if (a || test.addValue(10))
if (test.addValue(10) || a)
sono due righe diverse di codice, che portano a
risultati diversi, e
tutto ciò non è molto bello!
Ugo

Eccoti una piccola classe che faceva parte di un esercizio per chiarirti un
po' meglio le idee. La funzione con gli effetti collaterali non viene
eseguita con gli "short circuit" AND e OR. Chiaramente se provi a scambiare i
valori delle due variabili booleane vedrai che viene eseguita comunque, in
quanto il primo valore non basta ad assicurarsi il risultato finale
dell'espressione.
package test;
public class Operatori {
  public static void main(String[] args) {
    boolean falso = false;
    boolean vero = true;
    if (falso & Operatori.bool()){
      System.out.println("Full AND: Vero...");
    }
    else System.out.println("Full AND: Falso...");
    if (falso && Operatori.bool()){
      System.out.println("Short circuit AND: Vero...");
    }
    else System.out.println("Short circuit AND: Falso...");
    if (vero | Operatori.bool()){
      System.out.println("Full OR: Vero...");
    }
    else System.out.println("Full OR: Falso...");
    if (vero || Operatori.bool()){
      System.out.println("Short circuit OR: Vero...");
    }
    else System.out.println("Short circuit OR: Falso...");
  }
  public static boolean bool(){
    System.out.println("Effetti collaterali!");
    return true;
  }
}


ICQ #34602650

 particolari.
Momento. Il fatto che l'and logico && sia eseguito "alla C",
ovvero la valutazione avvenga nell'ordine di dichiarazione e
ritorni false appena uno degli operandi e' false e' abbastanza
marginale - e non vale certo per ||, per il quale, ovviamente,
tutti gli operandi vanno valutati per ottenere il valore (booleano)
dell'espressione.
Il punto e' che | e & sono bitwise operators, || e && operatori
logici.
Inoltre java, al contrario di C/C++, *non* fa l'equivalenza
implicita (0=false, <nonzero>=true) e non esegue conversioni
implicite da boolean a numerico o viceversa. In altri termini
if (1) { ... }
e' corretto (e pratica corrente) in C/C++, errato (e non compila)
in java.


 dell'espressione.
No, questo non è corretto.
(a || b) è già definita se a == true, e in tal caso non è necessario
valutare b. E java non lo fa.
In questo caso la cosa può apparire indifferente, ma se facciamo:
if(isBianco() || isNero())
il risultato può essere abbastanza diverso se la valutazione è completa,
parziale, da destra a sinistra o da sinistra a destra. Se isBianco()
ritorna true il metodo isNero() non viene nemmeno eseguito e questo può
essere fondamentale per la funzionalità del programma (dipende da cosa
fa il metodo al suo interno).


 No, questo non è corretto.
Vero.


 boolean2 = (10 > 5) & (5 > 1);
                      ^
Anche se proviene dalla documentazione ufficiale è sbagliata.
L'operatore & non ritorna un booleano e non c'è conversione implicita
fra int e booleano, per cui questa espressione non potrà essere
accettata dal compilatore. Presumo che dovesse essere &&.


> Sono anche bitwise operators, come sono anche operatori booleani.
No, sono proprio solo numerici. Se compili, che so,
class C { static { if (1 & true); } }
il compilatore riporta un errore. Nella specifica che hai letto ci
dev'essere un typo - o magari e' un taglia e incolla di quella di oak
;-)


 ;-)
Mah! La classe che ho spedito a me compila perfettamente (JB2.0) e
funziona come ci si aspetterebbe.
Mi informerò meglio!
--
°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
Enterprise Java Consulting
@mail: Ugo.L...@Flashnet.it
Home URL: 
http://www.ugolandini.net
Sample Work: 
http://www.sirena.lomb.cgil.it
Work Phone: 02/26254326
Cell Phone: 0347/6310749 - 0347/4783580
°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°

 Presumo che dovesse essere &&.
No. Fa una distinzione molto precisa fra && (short circuit AND) e &
(evaluation AND).
Ugo


 class C { static { if (1 & true); } }
Questo è un errore comunque, mischi numerici e booleani.


Marco Sarti wrote:

Anche se proviene dalla documentazione ufficiale
è sbagliata.

Qui, scusa, (e lungi da me la voglia di polemizzare) mi sembri un pochino
presuntuoso. Dove sta la verità, sulla documentazione ufficiale
Sun, nei programmi che girano o dove altro? Ho postato del codice 
funzionante,

un brano tratto dai docs Sun e la risposta continua ad essere che Java
non è come C++? Questo lo sapevo già dal 1996!

Comunque ho fatto un giro e ho risolto il 
mistero,
 così
posto questo brano che è tratto da "Thinking in Java", cap.3 pag.103
della versione online (diversa da quella stampata che al momento non ho
sottomano):

"The 
boolean
 type is treated as a one-bit value so it is somewhat
different. You can perform a

bitwise AND, OR and XOR, but you can’t perform a bitwise NOT (presumably
to prevent

confusion with the logical NOT). For booleans the bitwise operators
have the same effect as

the 
logical
 operators except that they do not 
short circuit
.
Also, the bitwise operators on

booleans gives you a XOR logical operator that is not included under
the list of “logical”

operators. You’re prevented from using booleans in shift expressions,
which is described

next".

Così, sono operatori booleani a tutti gli effetti. Ve l'avevo
detto di testare il codice, ve l'avevo detto, e invece voi subito ad attaccarmi,
malfidati! ;-)



 attaccarmi, malfidati! ;-)
Ammetto la svista (confesso di non aver visto che gli operandi erano
booleani, avevo assunto fossero numerici). Tuttavia la mia prima
contestazione alla tua risposta resta valida.


Marco Sarti wrote:

Il brano dimostra in sostanza quello che contestavo
inizialmente alla

tua prima risposta (prima che divagassimo), in cui dicevi che la

differenza fra & e && (oppure | e ||) si limitava nel fatto
che uno

applica lo short circuit mentre l'altro no.

Continuo a dire che mi riferivo all'applicazione degli operatori in questione
a parametri booleani, pensavo che la differenza fra bitwise e logical fosse
ovvia. Comunque sarebbe stato meglio specificare (vedi sotto)

Ovvero, specifica che questi operatori

hanno lo *stesso* *effetto* limitatamente ai *booleani* (che abbiamo

visto costituiscono un caso particolare essendo trattati come one-bit

types).

Dunque sono 
anche
 operatori booleani, che restituiscono un boolean
ed operano solo su boolean, come del resto || e &&. E spero che
non si discuta oltre di questa cosa! ;)

Cioè, quello che ti contesto è che
tu hai espresso un confronto fra gli

operatori bitwise e logici sulla base di un caso particolare come quello

dell'applicazione dei bitwise sui booleani, dal quale non emergono
delle

differenze fondamentali.

Sono fondamentali eccome!

Mi pare assurdo ad esempio non sottolineare che

gli operatori bitwise operano bit-a-bit sono utilizzati comunemente
su

tipi numerici e per applicazioni *completamente* diverse dal semplice

confronto logico degli operandi.

Su questo sono daccordo. Probabilmente (ma chi lo sa?) ho valutato male
la domanda. Questo non toglie che aggiungere la parte che si riferisce
ai bitwise era doveroso ed utile, dire che non sono operatori logici o
che non funzionano così come ho descritto è tutto un altro
paio di maniche.

 

int res;

int value;

int mask = 0x000000ff;

...

res = value & mask;

E' ancora un operatore booleano?

Forse non ci stiamo capendo. So benissimo come funzionano quando usati
come bitwise operators, e questo non è mai stato in discussione.
Quando applicati a valori logici, si comportano esattamente come gli evaluation
OR e AND (e non sono io a chiamarli così, sta sui doc), quindi a
tutti gli effetti sono operatori diversi quando applicati in contesti diversi.
Che si ottenga questo tramite un trattamento particolare del boolean come
1bit value non fa alcuna differenza. Esistono i bitwise operators e i logical
operators, che lavorano solo su booleani e restituiscono solo booleani.
I logical operators possono fare una valutazione piena o meno della condizione,
a seconda che si usi la versione strict o quella evaluation dell'operatore.
Questa era la mia risposta, non avendo tenuto conto per nulla degli operatori
bitwise (probabilmente a torto, lui voleva sapere proprio questa cosa:
io invece pensavo si riferisse alla sottile differenza di comportamento
in quanto operatori logici, che non è da poco e, ripeto, può
portare a errori difficili da scovare)

Ugo

P.S. Concentriamoci su qualcosa di più importante!

 

°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°

Enterprise Java Consulting

@mail: Ugo.L...@Flashnet.it

Home URL: 
http://www.ugolandini.net


Sample URL: 
http://www.sirena.lomb.cgil.it



°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°

 


 JB 2.0 (1.1.6 mi sembra) lo accetta alla grande
Occhio che jbuilder, a meno che tu non lo abbia settato in modo strano,
uso un suo compilatore (bcj.exe).
Non che questo volgia dire che sia meno affidabile di quello sun, anzi,
potrebbe essere piu' vicino alle specifiche di quanto non lo sia l'
altro.
Era solo una precisazione, al di la' dell' argomento del thread.
Ciao
-- 
il regolamento e' reale fino al punto in cui decidi di crederci ;-)

 Tutto qui. :)
Infatti dice
The && operator is like & (§15.21.2), but evaluates its right-hand
operand only if the value of its left-hand operand is true. It is
syntactically left-associative (it groups left-to-right).ecc.


 a me sa un po' di overloading: in fondo fa due cose diverse. No ?
Non direi. Il tipo boolean è trattato come un tipo formato da un solo
bit. Per questa ragione l'operatore logico e l'operatore bitwise hanno
lo stesso effetto sui boolean (escludendo lo short circuit, ovviamente).
