2014-07-03 78 views
2

有人能解釋一下下面的函數增量的挫折感:該功能如何增加?

function increment (i) { 
    i ^= (i & ~-~i) | (~i & -~i) 
    return i 
} 

我想我知道的JavaScript,但是當我看到上面的東西,我很惱火。

+0

提示:'〜i'是2的補碼中的'-i + 1'。 –

+1

這裏有一些閱讀:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators – athms

+0

或https://developer.mozilla.org/en/docs/Web/JavaScript/參考/運算符/ Bitwise_Operators – Miki

回答

5

布爾代數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à!

注意+如果我們想要完全正式的話應該被正式化爲另一個操作符。在這種情況下,我們可以安全地跳過定義並將其保留爲黑盒,因爲我們不需要任何屬性。唯一重要的是~的優先級高於+

+1

也許使用'0'而不是'false'? – Bergi

+0

@Bergi所有的表達式都應該是(或多或少)布爾代數表達式,而不是JS代碼(儘管它們也是有效的JS):) –

+0

但是它們實際上對「布爾值數組」操作 - 所以'[false * 32]':-) – Bergi

2

這裏的一個較短的證明,由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被使用,與xiy-~i

在「補碼的定義」步驟中,使用了定義-x = ~x + 1,其中x~i

+0

不錯,不幸的是,很難看到「xor」的定義在網站上取代了什麼。也許你可以使用更多的顏色? – Bergi

+0

@Bergi這是一個好主意,我會看看我能做什麼(需要一段時間) – harold

+0

不錯的網站。感謝您的新書籤。 – Phlume