有人能解釋一下下面的函數增量的挫折感:該功能如何增加?
function increment (i) {
i ^= (i & ~-~i) | (~i & -~i)
return i
}
我想我知道的JavaScript,但是當我看到上面的東西,我很惱火。
有人能解釋一下下面的函數增量的挫折感:該功能如何增加?
function increment (i) {
i ^= (i & ~-~i) | (~i & -~i)
return i
}
我想我知道的JavaScript,但是當我看到上面的東西,我很惱火。
布爾代數101
首先,我們與two's complement工作的假設下,這是元減運算符-
的定義(見太腳註):
-A = ~A + 1
這裏是你的RHS表達,有一些額外的加括號,沒有快捷方式分配,並與所有運營商在推廣形式更好的可讀性:
i xor ((i and ~(-(~i))) or (~i and -(~i))
我們應用第一關係:
i xor ((i and ~(~~i + 1)) or (~i and (~~i + 1))
補運算符~
是冪等,這意味着~~i
等於i
,所以我們簡化:
i xor ((i and ~(i + 1)) or (~i and (i + 1)))
的xor
運營商的第二項具有(X and ~Y) or (~X and Y)
形式,這意味着「X和Y之一必須是真的表達爲真,但不是兩個」,其中非常定義的排他或(xor
),所以我們可以替換與X xor Y
,獲得:
i xor (i xor (i + 1))
我們改變了協會(xor
是關聯的),我們得到:
(i xor i) xor (i + 1)
i xor i
是一對矛盾(總是false
),所以我們得到:
false xor (i + 1)
請注意,false xor X
的真值完全取決於X
,所以我們可以把上面的爲:
i + 1
所以RHS計算結果爲i + 1
。我們將其替換爲原始代碼,我們得到:
function increment(i) {
i = i + 1
return i
}
Voilà!
注意:+
如果我們想要完全正式的話應該被正式化爲另一個操作符。在這種情況下,我們可以安全地跳過定義並將其保留爲黑盒,因爲我們不需要任何屬性。唯一重要的是~
的優先級高於+
。
這裏的一個較短的證明,由my website
i^(i & ~-~i | ~i & -~i)
definition of xor
i^i^-~i
xor with self
-~i
definition of two's complement
~~i + 1
double complement
i + 1
在步驟 「XOR的定義」 自動生成,定義x^y = x & ~y | ~x & y
被使用,與x
是i
和y
是-~i
。
在「補碼的定義」步驟中,使用了定義-x = ~x + 1
,其中x
爲~i
。
提示:'〜i'是2的補碼中的'-i + 1'。 –
這裏有一些閱讀:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators – athms
或https://developer.mozilla.org/en/docs/Web/JavaScript/參考/運算符/ Bitwise_Operators – Miki