2012-04-05 19 views
9

Veo que esta pregunta ya se ha hecho, sin embargo, las respuestas fueron un poco vagas e inútiles. De acuerdo, necesito implementar una expresión c usando solo "&^~! + | >> < <"Declaración condicional usando operadores Bitwise

La expresión debe parecerse a: a? b: c

Así, a partir de lo que he sido capaz de decir, la expresión tiene que ser algo como:

return (a & b) | (~a & c)

Esto funciona cuando a = 0, porque anding con B asumirá cero, y luego la expresión o devolverá el lado derecho, (~a & c), que funciona porque ~ 0 da todos los unos, y al hacer que c con todos devuelva c.

Sin embargo, esto no funciona cuando a> 0. ¿Puede alguien tratar de explicar por qué ocurre esto, o cómo solucionarlo?

Respuesta

15

Convertiría a a un booleano usando !!a, para obtener 0 o 1. x = !!a.

Entonces lo negaría en complemento a dos. Como no tiene disponible unario menos, usa la definición de negación del complemento a 2: invierta los bits, luego agregue uno: y = ~x + 1. Eso dará todos los bits claros, o todos los bits establecidos.

Entonces yo and que directamente con una variable y & b, su inversa con la otra: ~y & c. Eso dará un 0 para una de las expresiones, y la variable original para la otra. Cuando nos or los juntos, el cero no tendrá ningún efecto, por lo que obtendremos la variable original, sin cambios.

+0

Esto es realmente perfecto. Entonces, ¿por qué agregar uno hace que todo esté definido o sea claro? Entiendo por qué eso tiene que suceder, pero no entiendo cómo sucede eso. – atb

+0

Si comenzamos con 0, luego voltear los bits da todos los. Cuando agregamos uno, todos vuelven a ceros (y el acarreo se establece, pero lo ignoramos). Si comenzamos con 1, voltear los bits da 111 ... 10. Al agregar 1, el último 0 pasa a ser 1, por lo que todos los bits son ahora 1. –

+0

la parte 'y = ~ x + 1' me confundió; Finalmente me di cuenta de que funciona debido al desbordamiento de enteros en caso de que x = 0, pero no es obvio. La solución más clara para mí fue primero cambiar lsb a msb con desplazamiento a la izquierda (00000001 => 10000000) y luego copiar msb con el desplazamiento a la derecha: 'y = (x << 31) >> 31' –

3

En otras palabras, es necesario tener a todos los bits puestos a 0, si a es false (es decir, 0), y se han establecido todos los bits a 1, si a es verdad (es decir a > 0).

Para el primer caso, el trabajo ya está hecho para usted; para este último, intente calcular el resultado de la expresión ~!1.

+0

Bueno, eso es lo que pensé al principio. ~! 1 daría todos los que es perfecto. Sin embargo, si tuviera que hacer ~! A, y a = 0, entonces ~! 0 me daría 1110, así que no estoy seguro de qué hacer desde aquí /: – atb