210

为什么〜2等于-3?运营商是如何~工作的?

4

18 回答 18

319

请记住,负数存储为正数的二进制补码。例如,以下是二进制补码中 -2 的表示:(8 位)

1111 1110

你得到这个的方法是取一个数字的二进制表示,取它的补码(反转所有位)并加一。两个从 0000 0010 开始,通过反转位我们得到 1111 1101。加一个得到上面的结果。第一位是符号位,表示负数。

那么让我们看看我们如何得到~2 = -3:

再来两个:

0000 0010

简单地翻转所有位,我们得到:

1111 1101

那么,二进制补码中的 -3 是什么样的?从正3开始:0000 0011,将所有位翻转为1111 1100,加一成为负值(-3),1111 1101。

因此,如果您只是将 2 中的位取反,您将得到 -3 的二进制补码表示。

补码运算符 (~) 只是翻转位。由机器来解释这些位。

于 2009-04-26T18:35:04.250 回答
44

~翻转值中的位。

为什么~2-3数字如何按位表示有关。数字表示为二进制补码

所以,2是二进制值

00000010

~2 翻转位,所以现在的值是:

11111101

其中,是-3的二进制表示。

于 2009-04-26T18:33:01.570 回答
21

正如其他人提到的那样~,只是翻转了位(将 1 更改为 0,将 0 更改为 1),并且由于使用了二进制补码,因此您得到了所看到的结果。

要添加的一件事是为什么使用二进制补码,这是为了使对负数的运算与对正数的运算相同。想像为了得到零-33应该添加的数字,你会看到这个数字是1101,记住二进制加法就像小学(十进制)加法一样,只有当你得到 2 而不是 10 .

 1101 +
 0011 // 3
    =
10000
    =
 0000 // lose carry bit because integers have a constant number of bits.

因此1101-3翻转你得到0010的两个位。

于 2009-04-26T20:04:18.450 回答
9

这个操作是一个补充,而不是一个否定。

考虑 ~0 = -1,然后从那里开始工作。

求反的算法是“补,增”。

你知道吗?还有一个反数对称的“反码”,它同时具有 0 和 -0。

于 2009-04-26T20:22:13.617 回答
8

我知道这个问题的答案是很久以前发布的,但我想分享我的答案。

要找到一个数的补码,首先要找到它的二进制等价物。这里,十进制数以二进制形式2表示0000 0010。现在通过反转其二进制表示的所有数字(将所有 1 翻转为 0,将所有 0 翻转为 1)来取其一个补码,这将导致:

0000 0010 → 1111 1101

这是十进制数2的反码。由于二进制数的第一位,即符号位是1,这意味着它存储的数字的符号为。(这里所指的数字不是2,而是 2 的反码)。

现在,由于数字存储为 2 的补码(取一个数字的补码加 1),所以要将这个二进制数 , 显示1111 1101为十进制,首先我们需要找到它的 2 的补码,即:

1111 1101 → 0000 0010 + 1 → 0000 0011

这是 2 的补码。二进制数 的十进制表示0000 00113。而且,由于符号位如上所述是 1,所以得到的答案是-3

提示:如果你仔细阅读这个过程,那么你会发现一个补码运算符的结果实际上是数字(操作数 - 应用此运算符)加上一个负号。您也可以尝试使用其他号码。

于 2014-04-04T18:40:10.493 回答
5

诠释一个= 4; System.out.println(~a); 结果将是:-5

java中任何整数的'~'代表数字的1的补码。例如我取〜4,这意味着二进制表示0100。首先,整数的长度是四个字节,即4 * 8(1字节8位)= 32。所以在系统内存中 4 现在表示为 0000 0000 0000 0000 0000 0000 0000 0100 ~ 运算符将对上述二进制数执行 1 的补码

即1111 1111 1111 1111 1111 1111 1111 1011->1的补码最高有效位表示否的符号(-或+)如果它是1然后符号是'-'如果它是0然后符号是'+'根据这个我们的结果是一个负数,在java中负数以2的补码形式存储,我们必须将获得的结果转换为2的补码(首先执行1的补码,然后将1加到1的补码)。除了最高有效位 1 (这是我们的数字的符号表示)之外,所有 1 都将变为零,这意味着剩余的 31 位 1111 1111 1111 1111 1111 1111 1111 1011 (获得 ~ 运算符的结果) 1000 0000 0000 0000 0000 0000 0000 0100(1 的补码)

1(2 的补码)

1000 0000 0000 0000 0000 0000 0000 0101 现在结果是 -5 查看此视频链接 <[Java 中的位操作符] https://youtu.be/w4pJ4cGWe9Y

于 2017-07-14T07:21:27.457 回答
3

简单地 ...........

作为任何数字的 2 的补码,我们可以通过将所有 1 反转为 0 来计算,反之亦然,而不是我们将 1 添加到它。

这里 N= ~N 总是产生结果 -(N+1) 。因为系统以 2 的补码形式存储数据,这意味着它像这样存储 ~N。

  ~N = -(~(~N)+1) =-(N+1). 

例如::

  N = 10  = 1010
  Than ~N  = 0101
  so ~(~N) = 1010
  so ~(~N) +1 = 1011 

现在点是从哪里来的减号。我的观点是假设我们有 32 位寄存器,这意味着 2^31 -1 位参与操作,并保留一位在早期计算(补码)中发生变化的位,通常存储为符号位,通常为 1。我们得到的结果为~10 = -11。

〜(-11)=10;

如果 printf("%d",~0); 以上是真的 我们得到结果:-1;

但是 printf("%u",~0) 比结果: 4294967295 在 32 位机器上。

于 2014-12-23T20:04:09.707 回答
3

位补运算符 (~) 是一元运算符。

它按照以下方法工作

首先它将给定的十进制数转换为其对应的二进制 值。即在 2 的情况下,它首先将 2 转换为 0000 0010(到 8 位二进制数)。

然后它将数字中的所有1转换为0,并将所有零转换为1;然后数字将变为1111 1101。

这是 -3 的 2 的补码表示。

为了使用补码找到无符号值,即简单地将 1111 1101 转换为十进制 (=4294967293),我们可以在打印期间简单地使用 %u。

于 2015-09-18T10:36:22.960 回答
3

简单来说,~就是求对称值(到-0.5)。

~a并且a应该在0和-1的中间对称于镜子。

-5,-4,-3,-2,-1 | 0、1、2、3、4

~0 == -1
~1 == -2
~2 == -3
~3 == -4

其原因在于计算机如何表示负值。

说,如果正值用于1计数,负值则使用0

1111 1111 == -1

1111 1110 == -2; // add one more '0' to '1111 1111'

1111 1101 == -3; // add one more '0' to '1111 1110'

最后,~i == -(i+1).

于 2021-03-30T17:27:00.127 回答
2

我认为对于大多数人来说,混淆部分来自十进制数和有符号二进制数之间的差异,所以让我们先澄清一下:

对于人类十进制世界:01 表示 1,-01 表示 -1,对于计算机的二进制世界:101 表示 5,如果它是无符号的。101 表示 (-4 + 1) 如果有符号,而有符号数字位于位置 x。| X

所以 2 的翻转位 = ~2 = ~(010) = 101 = -4 + 1 = -3 混淆来自于混淆了有符号的结果(101=-3)和无符号的结果(101=5)

于 2017-02-09T04:16:24.313 回答
2

基本上行动是补充而不是否定。

这里 x= ~x 总是产生结果 -(x+1) 。

x = ~2

-(2+1)

-3

于 2019-04-30T07:56:55.357 回答
2

tl; dr ~翻转位。结果,符号发生了变化。~2是负数 ( 0b..101)。要输出负数,ruby请打印:-的二进制补码。正数按原样输出。~2-(~~2 + 1) == -(2 + 1) == 3

有一个内部值及其字符串表示形式。对于正整数,它们基本上重合:

irb(main):001:0> '%i' % 2
=> "2"
irb(main):002:0> 2
=> 2

后者相当于:

irb(main):003:0> 2.to_s
"2"

~翻转内部值的位。20b010~20b..101。两个点 ( ..) 代表无限个1'。由于结果的最高有效位 (MSB) 为1,因此结果为负数 ( (~2).negative? == true)。要输出负数,ruby打印-,然后是内部值的二进制补码。二进制补码是通过翻转位,然后添加来计算的1。的二进制补码0b..1013。像这样:

irb(main):005:0> '%b' % 2
=> "10"
irb(main):006:0> '%b' % ~2
=> "..101"
irb(main):007:0> ~2
=> -3

总而言之,它翻转了位,从而改变了符号。要输出一个负数,它会打印-,然后是~~2 + 1( ~~2 == 2)。

之所以ruby像这样输出负数,是因为它将存储的值视为绝对值的二进制补码。换句话说,存储的是0b..101. 这是一个负数,因此它是某个值的二进制补码x。要找到x,它对 进行二进制补码0b..101。是 的补码的补码x。这是x(例如~(~2 + 1) + 1 == 2)。

如果您应用于~负数,它只会翻转位(但会改变符号):

irb(main):008:0> '%b' % -3
=> "..101"
irb(main):009:0> '%b' % ~-3
=> "10"
irb(main):010:0> ~-3
=> 2

更令人困惑的是~0xffffff00 != 0xff(或任何其他 MSB 等于 的值1)。让我们稍微简化一下:~0xf0 != 0x0f. 那是因为它被视为0xf0一个正数。这实际上是有道理的。所以,~0xf0 == 0x..f0f。结果是负数。的二进制补码0x..f0f0xf1。所以:

irb(main):011:0> '%x' % ~0xf0
=> "..f0f"
irb(main):012:0> (~0xf0).to_s(16)
=> "-f1"

如果您不打算将按位运算符应用于结果,则可以将~其视为-x - 1运算符:

irb(main):018:0> -2 - 1
=> -3
irb(main):019:0> --3 - 1
=> 2

但这可以说没有多大用处。

一个例子假设你有一个 8 位(为简单起见)网络掩码,你想计算0' 的数量。您可以通过翻转位并调用bit_length( 0x0f.bit_length == 4) 来计算它们。但是~0xf0 == 0x..f0f,所以我们必须切断不需要的位:

irb(main):014:0> '%x' % (~0xf0 & 0xff)
=> "f"
irb(main):015:0> (~0xf0 & 0xff).bit_length
=> 4

或者您可以使用 XOR 运算符 ( ^):

irb(main):016:0> i = 0xf0
irb(main):017:0> '%x' % i ^ ((1 << i.bit_length) - 1)
=> "f"
于 2019-11-04T18:52:45.657 回答
2

这里,二进制(8 位)中的 2 是 00000010,其 1 的补码是 11111101,从 1 的补码中减去 1,我们得到 11111101-1 = 11111100,这里的符号是 - 因为第 8 个字符(从 R 到 L)是 1 找到 1补充那个没有。即00000011 = 3,符号为负,这就是我们在这里得到-3的原因。

于 2020-08-09T15:41:17.190 回答
2

这简单:

Before starting please remember that 
 1  Positive numbers are represented directly into the memory.
 2. Whereas, negative numbers are stored in the form of 2's compliment.
 3. If MSB(Most Significant bit) is 1 then the number is negative otherwise number is 
    positive.

您正在寻找〜2:

Step:1 Represent 2 in a binary format 
       We will get, 0000 0010
Step:2 Now we have to find ~2(means 1's compliment of 2)
                  1's compliment       
       0000 0010 =================> 1111 1101 

       So, ~2 === 1111 1101, Here MSB(Most significant Bit) is 1(means negative value). So, 
       In memory it will be represented as 2's compliment(To find 2's compliment first we 
       have to find 1's compliment and then add 1 to it.)
Step3:  Finding 2's compliment of ~2 i.e 1111 1101

                   1's compliment                   Adding 1 to it
        1111 1101 =====================> 0000 0010 =================> 0000 0010
                                                                      +       1
                                                                      ---------
                                                                      0000 0011 
        So, 2's compliment of 1111 1101, is 0000 0011 

Step4:  Converting back to decimal format.
                   binary format
        0000 0011 ==============> 3
        
       In step2: we have seen that the number is negative number so the final answer would  
       be -3
                                    
                                So, ~2 === -3
于 2020-12-29T20:54:51.253 回答
1

首先,我们必须将给定的数字拆分为其二进制数字,然后通过在最后一个二进制数字上添加来反转它。执行后,我们必须给前一个数字提供相反的符号,我们找到了补全 ~2=-3 解释: 2s 二进制形式是 00000010 更改为 11111101 这是一个补码,然后补全 00000010+1=00000011 这是三的二进制形式和 -sign Ie,-3

于 2015-02-11T15:47:24.667 回答
1

位运算符是一个一元运算符,根据我的经验和知识,它适用于符号和幅度方法。

例如 ~2 将导致 -3。

这是因为按位运算符将首先表示符号和幅度的数字,即 0000 0010(8 位运算符),其中 MSB 是符号位。

然后稍后它将采用负数 2,即 -2。

-2 在符号和大小上表示为 1000 0010(8 位运算符)。

后来它在 LSB (1000 0010 + 1) 上加了一个 1,得到 1000 0011。

这是-3。

于 2015-11-27T18:40:50.340 回答
1

Javascript 波浪号 (~) 将给定值强制为一个的补码——所有位都被反转。 这就是波浪号的全部作用。这不是自以为是的标志。它既不增加也不减少任何数量。

0 -> 1
1 -> 0
...in every bit position [0...integer nbr of bits - 1]

在使用 JavaScript 等高级语言的标准桌面处理器上,BASE10 有符号算术是最常见的,但请记住,它不是唯一的一种。CPU 级别的位会根据许多因素进行解释。在“代码”级别,在本例中为 JavaScript,它们根据定义被解释为 32 位有符号整数(让我们将浮点数排除在外)。把它想象成量子,那些 32 位同时代表了许多可能的值。这完全取决于您查看它们的转换镜头。

JavaScript Tilde operation (1's complement)

BASE2 lens
~0001 -> 1110  - end result of ~ bitwise operation

BASE10 Signed lens (typical JS implementation)
~1  -> -2 

BASE10 Unsigned lens 
~1  -> 14 

以上所有内容同时为真。

于 2017-03-30T14:51:02.630 回答
1

这是一种可以解释的方式:

让我们以为什么~2 = -3为例,(为简单起见使用8位系统进行解释)

1)我们有 2 ---> 00000010

2)我们可以得到〜2 ---> 11111101 #通过简单地切换位。

[但常见的错误是有些人试图将直接获得的~2 的二进制值转换为十进制(以 10 为底)数字,在这种情况下,它是 253。这不是我们找到补码的方式。]

3) 现在我们找到一个二进制数,将其与 2~ 的二进制值相加得到 0 (00000000) 作为结果。在这种情况下,它是 00000011(即 3),因为如果我们将 00000011 加到我们拥有的 11111101 中,我们得到 100000000,但是由于我们使用的是 8 位系统并且 1 在第 9 位,所以它被忽略了完全,所以我们最终得到 00000000。

4)从第(3)点我们可以说~2+3 = 0,因此我们可以说~2 = -3

注意:-3 的值就是 11111101,可以用同样的方式解释。

于 2021-09-19T13:33:04.960 回答