Operações de precedência e máscara de bits

94

Eu me deparei com um caso (aparentemente) muito estranho.

Pegue o número 2 ( 0b10) e mascare-o com 1 ( 0b01)

Isso deve produzir o 0b00que é equivalente a 0.

No entanto, é aqui que entra o Sr. Schrödinger:

var_dump(0b10 & 0b01); // int(0)
var_dump(0b10 & 0b01 == 0); // int(0)
var_dump(0b10 & 0b01 != 0); // int(0)

Uísque. Tango. Foxtrot.

Reconheço que não sou o mais perspicaz quando se trata de operadores bitwise - então talvez eu tenha me enganado terrivelmente, terrivelmente errado em algum lugar?

No entanto, em Python:

0b10 & 0b01 == 0 = True

0b10 & 0b01 != 0 = False

...tão?

Danny Kopping
fonte
Não uso PHP, mas em C, C ++, você poderia simplesmente escrever comovar_dump(!(0b10 & 0b01))
Grijesh Chauhan
2
Porém, algo mais estranho: 0b0+1avalia para 2em algumas versões, devido a um bug do analisador.
Lily Chung

Respostas:

150

Você está realmente fazendo isso:

var_dump(0b10 & (0b01 == 0));
var_dump(0b10 & (0b01 != 0));

Experimentar:

var_dump((0b10 & 0b01) == 0);
var_dump((0b10 & 0b01) != 0);
Mateus
fonte
6
Parece-me que o PHP tem precedência geral do operador strnage.
Alvin Wong
23
Acho que é por isso que NUNCA confio na precendência em nenhum idioma. Além disso, acho que os parênteses tornam o código mais legível. Em casos extremos, você pode querer (re) agrupar e fazer pequenos comentários.
Sem resposta
2
@AlvinWong Você está correto! Acho que raramente um código precisa de expressão condicional, como 0b10 & (0b01 == 0)por que alguém aplicaria bit a bit com sim nenhum tipo de informação.
Grijesh Chauhan
4
Bem, considere um exemplo mais comum: o operador ternário, PHP, o tem ao contrário, o que o torna diferente de todas as outras linguagens. Ref: phpsadness
Alvin Wong
5
É por isso que em C e C ++ as pessoas têm avisos para essas coisas.
PlasmaHH