Ver Mensaje Individual
  #6 (permalink)  
Antiguo 10/05/2013, 19:07
Avatar de bulter
bulter
 
Fecha de Ingreso: enero-2008
Mensajes: 137
Antigüedad: 16 años, 2 meses
Puntos: 20
Respuesta: Importancia de los Bitwise

No soy gran experto en los bitwise, la verdad, pero...
Los bitwise por ejemplo son muy útiles para bitmask.
( Supongo que sabes que son los numeros binarios si llegas a preguntar esta pregunta )
Te dare un ejemplo.
Un sistema de permisos donde tienes:

Cita:
- Usuario (user)
- VIP (vip)
- Moderador (mod)
- Administrador (admin)
A cada uno de estos permisos se le asigna un numero
cada numero decimal tiene su binario correspondiente.

Cita:
User = 1 ( Binary: 0001 )
VIP = 2 ( Binary: 0010 )
Mod = 4 ( Binary: 0100 )
Admin = 8 ( Binary: 1000 )
Como ya sabras las operaciones bitwise se portan con sus operandos como una secuencia de bits. Cojeemos por ejemplo el operario | y los numeros 1 ( 0001 ) y 2 ( 0010 ). El operario | da 1 si el numero "A" o el numero "B" es 1:

Cita:

0001
|
0010
----------
0011 // Resultado
el operario & devuelve 1 SOLO si el numero "A" y el numero "B" son 1:

Cita:
0001
&
0010
----------
0000 // Resultado

0001
&
0001
----------
0001 // Resultado
Sabiendo esto se puede hacer un rang check, log level, buttons to show etc. guapos.
Te dare ejemplos:

RANGOS
Código PHP:

<?php
const RANG_USER 1// Binary: 0001
const RANG_VIP 2// Binary: 0010
const RANG_MOD 4// Binary: 0100
const RANG_ADMIN 8// Binary: 1000

$userRang RANG_VIP RANG_MOD;

if(
!= ($userRang RANG_VIP))
{
    echo 
"Yes";
}

?>
Explico el codigo de arriba.
Se definen 4 rangos ( 4 constantes ) de los usuarios, a cada se le asigna un numero.
Luego le damos al usuario rangos. Que pasa en esta linea:

Cita:
$userRang = RANG_VIP | RANG_MOD;
Ya que usamos el operario | veamos cual seria el valor de $userRang

Cita:
RANG_VIP 0010
|
RANG_MOD 0100
--------------------------
0110
El valor que obtendrá $userRang seria 0110.
En la siguiente linea lo que hacemos es comprobar si el permiso que se pide existe.
Como se hace ?! Comprobando si el contenido de $userRang contiene el valor 1 en la posición requerida.

Cita:
if(0 != ($my_perm & RANG_VIP))
En el caso si que tiene, asi que veamos lo que pasa en esta linea

Cita:
RANG_VIP 0110
&
RANG_VIP 0010
------------------------
0010
en este caso ($my_perm & RANG_VIP) NO es igual a 0 y tendra permisos.
Si queremos subir le rango nada mas movemos 1 bit hacia la izquierda:

Código PHP:
$userCurrentRang RANG_USER//  1 o 0001
$userNewRang RANG_USER << 1// ( movemos 1 bit hacia la izquierda ) 2 o 0010 ( El usuario ya es VIP )
$userToAdmin RANG_USER << 3// ( movemos 3 bits hacia la izquierda ) 8 o 1000 ( El usuario ya es Admin ) 

Como dije se puede usar para otra cosas, digamos botones ( es si programas GUI )
(Usare codigo PHP aun que no se puede hacer , pero es para dar ejemplo)

Código PHP:
<?php
const BTN_NO 1;
const 
BTN_YES 2;
const 
BTN_CANCEL 4;

function 
alertWindow($buttons)
{
    if(
$buttons BTN_YES)
    {
        echo 
"[YES]";
    }
    
    if(
$buttons BTN_NO)
    {
        echo 
"[NO]";
    }
    
    if(
$buttons BTN_CANCEL)
    {
        echo 
"[CANCEL]";
    }
}

alertWindow(BTN_YES BTN_NO);
?>
Lo bueno de esto?
Imaginemos la otra posible forma de este codigo

Código PHP:
<?php
function alertWindow($btnYes$btnNo$btnCancel)
{
    if(
$btnYes == true)
    {
        echo 
"[YES]";
    }
    
    if(
$btnNo == true)
    {
        echo 
"[NO]";
    }
    
    if(
$btnCancel == true)
    {
        echo 
"[CANCEL]";
    }
}

alertWindow(falsefalsetrue);
?>
Para definir que querremos solo el botón cancel necesitamos 3 parámetros, dos de los cuales son absolutamente innecesarios. Usando bitwise solo indicamos que botones necesitamos.

Otro ejemplo de uso similar seran los logs ( que tipos de logs escribir / mostrar y cuales ignorar )

El operario ^ también puede ser muy util. El operario ^ devuelve 1 SOLO cuando numero "A" y numero "B" son distintos.
Un ejemplo de su uso podria ser:

Código PHP:
$firstValue true;
$secondValue false

if(
$firstValue $secondValue)
{
    echo 
"YES";

En este codigo se mostrara YES solo y cuando 1 de las dos variables es true, pero no las 2 a la vez.
Para todo esto de aqui puedo decir que usamos los numeros binarios interruptores on/off ( 0 off y 1 on ).

Como dijo pateketrueke se usan también para hacer operaciones con los colores, por ejemplo cojer en un HEX color cuanto azul/verde/rojo hay.
Los colores se representan en la forma ARGB o ABGR donde

Cita:
A = Alpha/transparency
R = Red
G = Green
B = Blue
La forma standart de escribir los colores en HEX es 0xAARRGGBB donde cada letra representa un numero hexdecimal.
Los primeros dos numeros hexdecimales son los primeros 8 numeros binarios que representan el Alpha, los siguientes 8 bits representan el rojo, despues verde y azul ( Si hablamos de RGB ) . En el color 0x0000FF para cojer la cantidad de color azul que habra que hacer ?!
Primero Convirtamos el hex en binary para poder ver lo mas claro

Cita:
0000FF => 00000000 00000000 11111111
Ahora para extraer el azul, tenemos que borrar o enmascarar todo aquella informacion que no nos hace falta ( en el caso el rojo y el verde )

(el operario & devuelve 1 SOLO si el numero "A" y el numero "B" son 1)

Cita:
0000FF => 00000000 00000000 11111111
&
00000000 00000000 11111111
---------------------------------------------------------
00000000 00000000 11111111

Para mas claridad (ejemplo con el color #0000F5)
0000F5 => 00000000 00000000 11110101
&
00000000 00000000 11111111
-------------------------------------------------------
00000000 00000000 11110101
Un codigo PHP de ejemplo podria ser:

Código PHP:
$color 0xABC5E2;


// 0xFF == 11111111 binary
$red = ($color >> 16) & 0xFF// El rojo son los primeros 8 bits asi que nos movemos 16 bits a la izquierda
$green = ($color >> 8) & 0xFF// El verde es al centro asi que nos movemos 8 bits a la izquierda
$blue $color 0xFF;

echo 
"RED: " $red "<br />";
echo 
"GREEN: " $green "<br />";
echo 
"BLUE: " $blue "<br />"
Bueno mas o menos es esto no se si me explicado bien .. pero espero que te ha servido de algo :))

Saludos.