Alguém me explica isso?

Alguém consegue explicar o pq dos valores finais de x e y?

public class Sample {
    public static void main(String[] args) {
        int x = 1984;
        int y = 2001;
        x ^= y ^= x ^= y;
    }
}

o y retornar 1984 do ou exclusivo ta até blz

to tentando entender é pq o x deu 0

:frowning:

[quote=caduengenheiro]o y retornar 1984 do ou exclusivo ta até blz

to tentando entender é pq o x deu 0

:frowning: [/quote]

É o verdadeiro x da questão… :lol: :lol: piadinha infame…

hehe

realmente… hehe

ainda nao cheguei no cap 3 da kathy… hehe

eu to no cap3 mais n cheguei a esse topico ainda… mais so olhando a sintaxe… nao conseguir entender o pq tb

Olá,

Não sei se ajuda para entender, mas

é equivalente do:

E os valores dos variáveis ficam avaliados antes de qualquer operação XOR.

Ou seja, mesmo que o x é atribuído o valor 17 em x ^= y a operação final para determinar o valor (final) do x fica 1984 ^ 1984. Onde o primeiro 1984 é o valor inicial do x e o outro 1984 é o resultado da y ^= x ^= y.

[]s,
Sami

hehehe este ehn um bug do java 1.4

vejam em:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4672380

até +

Dieval

Sami,

eu acho que existe equivo nos calculos… vejamos os meus:

x = 11111000000 1984
y = 11111010001 2001

x ^= y ^= x ^= y;

x = x ^ (y = y ^ (x = x ^ y))

o resultado do parentes mais interno:
x = 00000010001 17

x = x ^ (y = y ^ 17)

y = 11111010001
x = 00000010001
y = 11111000000 (1984)

x = 17 ^ 1984

x = 00000010001
y = 11111000000 (1984)
x = 11111010001 (2001)

fw

Acho que entendi…

XOR sempre retorna 1 para operandos diferentes e 0 para operandos iguais…

sendo assim:

x ^= y ^= x ^= y;

primeiro:

vamos rescrever a expressão: x ^= y ^= x ^= y;
x = x ^ (y ^ (x ^ y))

x ^ y //alterou-se todos os valores de x de acordo com xor.

(y ^ (x ^ y)) // alterou-se todos os valores de y de acordo com xor, mas observer que se fez o contrário da primeira vez que resulta que y agora é igual ao primiero valor de x.

x = x ^ (y ^ (x ^ y)) equivale x = x ^ (mesmo valor de x), ou seja, x = 0…

humm, num sei, num estou certo se x ^= y ^= x ^= y equivale a x = x ^ (y ^ (x ^ y)) , o que vc’s acham?

É meio o que o Sami falou…

o lance é o do sami ai

x ainda nao atualizou seu valor na pilha pq a expressão ainda nao foi concluida … mas qto ao bug… eu rodei esse código no java 5 e deu 0 tb… entao acho que o bug nao eh somente do java 1.4

:wink:

[quote=Dieval Guizelini]hehehe este ehn um bug do java 1.4

vejam em:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4672380

até +

Dieval[/quote]

Esse foi reportado como um bug, mas o estado é:

E o estado do 4645646 é

A explicação dado porque isto não é um bug:

[quote=Dieval Guizelini]Sami,

eu acho que existe equivo nos calculos… vejamos os meus:

x = 11111000000 1984
y = 11111010001 2001

x ^= y ^= x ^= y;

x = x ^ (y = y ^ (x = x ^ y))

o resultado do parentes mais interno:
x = 00000010001 17

x = x ^ (y = y ^ 17)

y = 11111010001
x = 00000010001
y = 11111000000 (1984)

x = 17 ^ 1984

x = 00000010001
y = 11111000000 (1984)
x = 11111010001 (2001)

fw[/quote]

Dieval,

Mas foi justamente isso que eu quis dizer (com meu português limitado). Aquele 17 acima, que eu deixei destacado na verdade não é 17 e sim 1984, porque o valor daquele x foi “sampleado” antes de calcular aquele monte de XORs.

[]s,
Sami

public class XorSample {

     public static void main(String[] args) {
         // Este é o famoso truque de tentar trocar
         // dois valores com XOR, sem usar uma variável
         // local explicitamente. Infelizmente isso não funciona
         // em Java, embora costume funcionar em C/C++.
         int x = 1984;
         int y = 2001;
         x ^= y ^= x ^= y;
         // Testado com Microsoft JVC, Sun, IBM Jikes
         System.out.println ("x=" + x); // 0
         System.out.println ("y=" + y); // 1984

         // Isto é o equivalente exato da expressão acima
	 x = 1984;
         y = 2001;
         x = x ^ ( y = y ^ (x = x ^ y));
         System.out.println ("x=" + x); // 0
         System.out.println ("y=" + y); // 1984

         // Note que a segunda avaliação de x = x ^ ... é feita DEPOIS da primeira, 
         // não ao contrário. Isso é difícil até de acompanhar.
     }
}

Como de costume:

  • Isso é complicado demais para cair em uma prova de verdade.
  • É exatamente o que o Sami explicou.

Bom, eu mesmo duvidando o que eu disse, fiz um teste. E o código gerado pelo javac fica exatamente igual.

Um exemplo mais simples para demonstrar a mesma coisa:

         int x = 2;
         x = x * (x = 1);
         System.out.println(x);

Imprime o quê?

[]s,
Sami

2, mas afinal de contas, quando é feita a atribuição x = 1, ou ela simplismente não é feita? :shock:

[quote=Sami Koivu][quote=Dieval Guizelini]Sami,

eu acho que existe equivo nos calculos… vejamos os meus:

x = 11111000000 1984
y = 11111010001 2001

x ^= y ^= x ^= y;

x = x ^ (y = y ^ (x = x ^ y))

o resultado do parentes mais interno:
x = 00000010001 17

x = x ^ (y = y ^ 17)

y = 11111010001
x = 00000010001
y = 11111000000 (1984)

x = 17 ^ 1984

x = 00000010001
y = 11111000000 (1984)
x = 11111010001 (2001)

fw[/quote]

Dieval,

Mas foi justamente isso que eu quis dizer (com meu português limitado). Aquele 17 acima, que eu deixei destacado na verdade não é 17 e sim 1984, porque o valor daquele x foi “sampleado” antes de calcular aquele monte de XORs.

[]s,
Sami[/quote]

Certo Sami, mas você me disse um conceito que não conheço, ou deixar passar desapercebido por onde eu andei… qual a idéia do “sampleado”?

falou.

Heheh, desculpas, realmente não consegui encontrar uma palavra adequada em português. Em inglês seria o verbo “evaluate” ou “sample”. De qualquer forma eu estou querendo me referir ao ato de “substituir” um variável com o valor do mesmo, numa expressão.

Então

         int x = 2;
         x = x * (x = 1);
         System.out.println(x);

Imprime 2.

         int x = 2;
         x = (x = 1) * x;
         System.out.println(x);

Imprime 1.

O que acontece no primeiro código deve ser mais ou menos o seguinte:

A expressão x * (x = 1) é resolvido parte por parte segundo as regras de precedência. Aquele primeiro x é resolvido (o valor do x é 2 naquele momento).

O outro parte é resolvido, x é atribuído valor 1, e o valor da expressão (x = 1) é 1.

Ficamos com 2 * 1 e o resultado disso é colocado no x.

[]s,
Sami

mas se não for feita a atribuição x = 1, x vale 2 e 2 x 2 = 4.
Pra mim o comportamento do compilador foi o seguinte:
x = 2 * 1 = 2, ou seja ele coloca o 2 em um registrador, depois ele atribui 1 ao x, dentro do parenteses, coloca em outro registrador e faz 2*1=2.

Virxi acho q viajei. :shock:

[quote=RenatoMoura]mas se não for feita a atribuição x = 1, x vale 2 e 2 x 2 = 4.
Pra mim o comportamento do compilador foi o seguinte:
x = 2 * 1 = 2, ou seja ele coloca o 2 em um registrador, depois ele atribui 1 ao x, dentro do parenteses, coloca em outro registrador e faz 2*1=2.
[/quote]

Acho que meu português está me traindo aqui. O que eu quis dizer é que a atribuição é feito, sim. O que você disse está certo (o registrador sendo a pilha).