这个函数如何递增?

Mik*_*ike 2 javascript bit-manipulation increment

有人可以解释下面的功能如何增加:

function increment (i) {
  i ^= (i & ~-~i) | (~i & -~i)
  return i
}
Run Code Online (Sandbox Code Playgroud)

我想我知道javascript,但是当我看到上面的内容时,它会让我生气.

Ste*_*ppo 5

布尔代数101.

首先,在我们使用二进制补码的假设下,这是一元减运算符的定义-(也见脚注):

-A = ~A + 1
Run Code Online (Sandbox Code Playgroud)

这是您的RHS表达式,添加了一些额外的括号,没有快捷方式赋值,并且所有运算符都是扩展形式,以提高可读性:

i xor ((i and ~(-(~i))) or (~i and -(~i))
Run Code Online (Sandbox Code Playgroud)

我们应用第一个关系:

i xor ((i and ~(~~i + 1)) or (~i and (~~i + 1))
Run Code Online (Sandbox Code Playgroud)

补码运算符~是幂等的,意思~~i是等于i,所以我们简化:

i xor ((i and ~(i + 1)) or (~i and (i + 1)))
Run Code Online (Sandbox Code Playgroud)

xor运算符的第二项具有(X and ~Y) or (~X and Y)形式,这意味着"表达式为真,但不是两者都必须为X和Y之一",这是对exclusive或(xor)的定义,所以我们可以用它代替X xor Y,获得:

i xor (i xor (i + 1))
Run Code Online (Sandbox Code Playgroud)

我们改变了关联(xor是关联的),我们得到:

(i xor i) xor (i + 1)
Run Code Online (Sandbox Code Playgroud)

i xor i是一个矛盾(总是false),所以我们得到:

false xor (i + 1)
Run Code Online (Sandbox Code Playgroud)

请注意,真值false xor X完全取决于X,所以我们可以将上面的内容重写为:

i + 1
Run Code Online (Sandbox Code Playgroud)

所以RHS评估为i + 1.我们在原始代码中替换它,我们得到:

function increment(i) {
    i = i + 1
    return i
}
Run Code Online (Sandbox Code Playgroud)

瞧!

注意:+如果我们想要完全正式,应该正式化为另一个运营商.在这种情况下,我们可以安全地跳过定义并将其保留为黑盒子,因为我们不需要任何属性.唯一重要的是~优先级高于+.