为什么“$(( ~33 ))”产生-34?

gas*_*ter 15 shell bash arithmetic

$ echo $(( 255 ))
255
$ echo $(( 33 ))
33
$ echo $(( ~33 ))
-34
$ echo $(( ~255 ))
-256
$ 
Run Code Online (Sandbox Code Playgroud)

我的内核是:

$ 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
Run Code Online (Sandbox Code Playgroud)

问题: ~用于否定 AFAIK 数字。但是为什么~33产生-34,为什么~255产生-256

mic*_*has 24

bash 的手册页说:

   ! ~    logical and bitwise negation
Run Code Online (Sandbox Code Playgroud)

有符号数通常以二进制补码表示形式存储:

...
-4 = 1100
-3 = 1101
-2 = 1110
-1 = 1111
 0 = 0000
 1 = 0001
 2 = 0010
 3 = 0011
...
Run Code Online (Sandbox Code Playgroud)

这意味着,如果你采用像 2 这样的数字,它会被按位解释为 0010。按位求反后,它变成 1101,这是 -3 的表示。


Chr*_*own 11

这是二进制补码运算的结果。

~是一个按位否定,它反转所有被操作的位。二进制补码算法的工作原理是将所有位取反并加 1。由于您只翻转了位,但未加 1,因此您得到相同的数字,取反后减 1。

维基百科在这里有一篇关于二进制补码的好文章。

举个例子:

  • 3 二进制是 0011
  • -3 in(二进制补码)二进制是 1101
  • 反转0011为您提供1100-4,因为您还没有添加 1。