Diario de aprendizaje de GNU-linux

Día 32 Operadores nivel de bit en bash

  • Por defecto bash trata todo como caracteres o cadenas de caracteres, es por eso que si queremos hacer una operación aritmetica tenemos que ponerlo entre doble parentesis, ejemplo echo $((5 + 5)).

  • El simbolo $ o operador de expanción es en esencia un orden de intercambio o de extraccion, es decir, basicamente le dice a bash “no leas esto como texto litar; ve a mirar que hay dentro, resuelve lo que falta y entregame al resultado aqui mismo” si ago echo 5 + 5 bash me devolvera eso como texto plano, pero con el operador de expanción y los parentesis dobles bash entiende que es lo que se pretende hacer.

  • para entender los operadores bit a bit antes hay que entender como funciona el sisstema binario en hardware, asumiento que ya se entiende a nivel basico como funciona el sistema binario

  • conteo posicional: al igual que en el sistema decimal se cuenta de derecha a izquierda

  • Bits: un bit es la unidad minima de información que una computadora puede leer 0 o 1 cuando hablamos de computadoras de 8 16 32 o 64 bits nos referimos a la cantidad maxima de información que una computadora puede leer o procesar de la memoria RAM, por ejemplo si yo creo un numero en sistema binario ejemplo 0101 que en sistema decimal seria el 5, la computadora no lo lee solo como 0101 si no dependiendo del tipo de procesador, lo leera como un total de 64 digitos (en caso de que el procesador sea de 64 bits) cuyos primeros 4 digitos a la derecha del todo son 0101 y el resto de digitos se quedaran en 0.

  • ¿Por que es importante saber esto? al operar con bits en una computadora pueden pasar cosas extrañas si no se entiende bien esto, por ejemplo ¿como se representan numeros negativos en una computadora si solo entiende de 0 y 1? esto lo veremos mas adelante

  • Operadores bit a bit:

    • Nota: para poder decirle a bash en que sistema numerico estamos es necesario aclarandolo con # ejemplo ((2#)) es decir sistema base 2, en decimal por ejemplo de esta forma bash entiende en que sistema numerico queremos usasr

    • AND (intersección): El simblo para AND logico en bash es “&” echo $((2#0101 & 2#0011)) esto nos devolveria 1, puesto que la condición and necesita que hambas condiciones sean verdaderas para 1 y que solo 1 o hambas sean falsas para 0, si operamos los bits veremos que solo el primer digito de hambos operandos son 1, mientras en el resto son incompatibles, por lo tanto el resultado seria 0001 que en sistema decimal seria 1

    • OR(Unión): El simbolo para OR logico en bash es “|” echo $((2#0101 | 2#0011)) esto nos devolveria 7, puesto que al operar los bits vemos que almenos 1 de los primeros 3 digitos de hambos operandos son 1, por lo que el resultado seria 0111 que en sistema decimal seria 7

    • XOR(OR exclusivo): El simbolo para XOR logico es “^” echo $((2#0101 ^ 2#0011)) esto nos devolveria 6 puesto que el tercer digito del primer operando y el segundo digito del segundo operando tiene 1 y al operarse con el mismo digito del otro operando es 0, recordemos que XOR da como verdadero las condiciones cuya opciones solo 1 es verdadera y la otra falsa

    • NOT (Negación): El simbolo para NOT logico es “~” echo $((~2#0011)) esto nos devolveria -4 ¿por que? si lo logico seria pensar que sus operadores al negarse daria 1100 cuyo valor en sistema decimal es 12, esto sucede por lo que explique al principio, una computadora siempre creara el valor de un numero con la cantidad de digitos en bits que soporte su procesador, independientemente si yo ago 0011 el procesador por ejemplo de 64 bits creara 64 digitos cuyos primeros 4 a su derecha son 0011 y el resto serán 0 al negar cada digito no solo estoy negando el 0011 si no tambien el resto de digitos que estan en 0 a su izquienda, ¿pero entonces por que esos 1 no se suman y da un valor negativo? esto es por el complemento a dos

    • << (Desplazamiento a la izquierda): echo $((2#0011<<2)) esto desplaza los 2 primeros bits a la izquierda, en este caso 11, por lo que el resultado es 1100 que en decimal seria 12

    • >> (Desplazamiento a la derecha): echo $((2#1100>>2)) esto desplaza los 2 primeros bits a la derecha, en este caso 11 por lo que el resultado es 0011 que en decimal seria 3

  • complemento a dos:

  • El complemento a dos resuelve un problema, y es que las computadoras solo entienden de 0 y 1, no pueden entender un signo como el “-” para representar numeros negativos, por lo tanto el primer bit a la izquienda del todo es el que decide si un numero es positivo o negativo, si es 0 es positivo, si es 1 es negativo.

  • Aquí pasa algo muy interesante, y es que si el primer digito a la izquierda es 1, los 0 pasan a ser los valores positivos y los 1 los valores negativos, esto ademas de que se lee al reves, a la derecha estan los digitos mas grandes y a la izquierda los mas pequeños, por lo tanto si tengo ~2#0011 la computadora lo lee como 11111111…** cuyos primeros 4 digitos a su derecha son 1100, recordemos que ahora se lee de derecha a izquierda, por lo tanto los 1 son numeros negativos y los 0 son numeros positivos, eso significa que si restamos los 2 00 positivos a la derecha del todo con el resto de 1 el resultado es -4

1 me gusta