$ echo $(( 255 ))
255
$ echo $(( 33 ))
33
$ echo $(( ~33 ))
-34
$ echo $(( ~255 ))
-256
$
y mi núcleo es:
$ uname -a
Linux HOSTNAME 3.2.0-40-generic-pae #64-Ubuntu SMP Mon Mar 25 21:44:41 UTC 2013 i686 i686 i386 GNU/Linux
PREGUNTA: ~
es para negar el número AFAIK. Pero, ¿por qué ~33
produce -34
y por qué ~255
produce -256
?
bash
shell
arithmetic
Gasko Peter
fuente
fuente
Respuestas:
La página del manual de bash dice:
Los números firmados generalmente se almacenan en la representación complementaria de Two :
Esto significa que si toma un número como 2, se interpreta a nivel de bit como 0010. Después de la negación a nivel de bit, se convierte en 1101, que es la representación de -3.
fuente
Este es el resultado de la aritmética del complemento a dos.
~
es una negación bit a bit que invierte todos los bits sobre los que se opera. La aritmética del complemento a dos funciona invirtiendo todos los bits y sumando 1. Dado que solo ha volteado los bits, pero no ha agregado uno, obtiene el mismo número, invertido, menos uno.Wikipedia tiene un buen artículo sobre el complemento a dos aquí .
Como ejemplo:
0011
1101
0011
te da1100
, que es -4, ya que no has agregado 1.fuente
El operador ~ es el operador NO bit a bit. Usarlo no es lo mismo que negar un número.
De wikipedia , una operación NO a nivel de bit es igual a tomar el complemento de dos del valor menos uno:
Negar un número binario es equivalente a tomar su valor de dos complementos.
Usando el operador ~ NOT = tome su valor de un complemento.
En términos más simples, ~ simplemente voltea todos los bits de la representación binaria .
Para tus ejemplos:
O en aritmética decimal, usando la fórmula ~ x = -x - 1:
y
fuente
El problema es que ~ es un operador inteligente. Por lo tanto, está negando más bits de los que quizás pretende. Puede ver esto mejor al convertir los resultados a hexadecimal, por ejemplo:
versus lo que tenías:
Supongo que quieres negar 0x33. Si ese es el caso, entonces esto funcionaría:
También debe usar &, que es el bit-wise y el operador para evitar todo el ff al comienzo.
fuente
El
~
operador (aritmético) voltea todos los bits , se llama operador de negación bit a bit:Entonces, en lugares donde el contexto es aritmético, cambia un número con todos los bits como ceros a todos los bits como unos. A
$(( ~0 ))
convierte todos los bits de la representación numérica (generalmente 64 bits hoy en día) a todos.Un número con todos se interpreta como el número negativo (primer bit
1
)1
, o simplemente-1
.Lo mismo ocurre con todos los demás números, por ejemplo:
$(( ~1 ))
voltea todos los bits:O, en binario:
1111111111111111111111111111111111111111111111111111111111111110
Lo cual, interpretado como un número en la representación de dos es:
En general, la ecuación matemática humana
$(( ~n ))
es igual a$(( -n-1 ))
Y (tu pregunta):
fuente
Primero debe comprender que 33 es un número de 32 bits o de 64 bits.
Por conveniencia, tomo un número de ocho bits (= 1 byte)
el decimal 33 está en ocho bits: 00100001, voltear los bits da como resultado 11011110.
Como el bit de orden superior es 1, es un número negativo.
Al imprimir un número negativo, el sistema imprime un signo menos y luego hace un complemento de dos en el número negativo.
El complemento a dos es: voltear los bits y sumar 1.
11011110 ==> 00100001 ==> sumando 1 ==> 00100010 da como resultado 34 decimales detrás del signo menos.
fuente