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;
}
}
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
[quote=caduengenheiro]o y retornar 1984 do ou exclusivo ta até blz
to tentando entender é pq o x deu 0
[/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
[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:
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).