$ echo $(( 255 ))
255
$ echo $(( 33 ))
33
$ echo $(( ~33 ))
-34
$ echo $(( ~255 ))
-256
$
e meu kernel é:
$ 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
PERGUNTA: ~
é para negar o número AFAIK. Mas por que ~33
produzir -34
e por que ~255
produzir -256
?
bash
shell
arithmetic
gasko peter
fonte
fonte
Respostas:
A página de manual do bash diz:
Os números assinados são geralmente armazenados na representação do complemento do Two :
Isso significa que, se você pegar um número como 2, ele será interpretado em bits como 0010. Após a negação em bits, isso se tornará 1101, que é a representação de -3.
fonte
Este é o resultado da aritmética do complemento de dois.
~
é uma negação bit a bit que inverte todos os bits que estão sendo operados. A aritmética do complemento de dois funciona invertendo todos os bits e adicionando 1. Como você só inverteu os bits, mas não adicionou um, obtém o mesmo número, invertido, menos um.A Wikipedia tem um bom artigo sobre o complemento de dois aqui .
Como um exemplo:
0011
1101
0011
fornece1100
-4, pois você não adicionou 1.fonte
O operador ~ é o operador NOT bit a bit. Usá-lo não é o mesmo que negar um número.
Na wikipedia , uma operação NOT bit a bit é igual a obter o complemento de dois do valor menos um:
Negar um número binário é equivalente a obter seu valor de dois complementos.
Usando o operador ~ NOT = use seu valor de um complemento.
Em termos mais simples, ~ apenas inverte todos os bits da representação binária .
Para seus exemplos:
Ou na aritmética decimal, usando a fórmula ~ x = -x - 1:
e
fonte
O problema é que ~ é um operador pouco inteligente. Portanto, você está negando mais bits do que talvez pretenda. Você pode ver isso melhor convertendo os resultados em hexadecimal, por exemplo:
versus o que você tinha:
Suponho que você pretenda negar 0x33. Se for esse o caso, isso funcionaria:
Você também deve usar & qual é o operador e bit-wise para evitar todo o ff no início.
fonte
O
~
operador (aritmético) vira todos os bits , é chamado de operador de negação bit a bit:Portanto, em locais onde o contexto é aritmético, ele altera um número com todos os bits como zeros para todos os bits como um. A
$(( ~0 ))
converte todos os bits da representação numérica (normalmente hoje em dia, 64 bits) em todos.Um número com todos os números é interpretado como o número negativo (primeiro bit
1
)1
, ou simplesmente-1
.O mesmo acontece com todos os outros números, por exemplo:
$(( ~1 ))
vira todos os bits:Ou, em binário:
1111111111111111111111111111111111111111111111111111111111111110
O qual, interpretado como um número na representação de dois, é:
Em geral, a equação matemática humana
$(( ~n ))
é igual a$(( -n-1 ))
E (sua pergunta):
fonte
Primeiro você precisa entender que 33 é um número de 32 bits ou de 64 bits.
Por conveniência, pego um número de oito bits (= 1 byte)
decimal 33 está em oito bits: 00100001, invertendo os bits resulta em 11011110.
Como o bit de ordem superior é 1, é um número negativo.
Imprimindo um número negativo, o sistema imprime um sinal de menos e depois faz um complemento de dois no número negativo.
O complemento de dois é: virar os bits e adicionar 1.
11011110 ==> 00100001 ==> adicionar 1 ==> 00100010 resulta em 34 decimal atrás do sinal de menos.
fonte