JavaScript Bitwise NOT Operator

心血來潮地跑到Upworks作了個JavaScript Test,結果固然是慘不忍睹,發現本身對很多JavaScript的基礎知識的理解是模模糊糊,甚至是錯的。javascript

好比這題:html

~-(2+"2")java

這個表達式的值是21,我腦補了很久也得不到這個答案,這才發現,我徹底不理解Bitwise NOT操做符。python

不懂就補嘍。程序員

這回還真是「補」,回想起大學那會兒,學到「補碼」時,腦子裏就是一團霧,原來那團迷霧到今天也沒散,真他麼黏糊。this

讀到 Why is ~5 === -6 in JavaScript?:code

It does indeed perform a bit-wise NOT, the negative number is in two's complement. So the value 1010 is -6.

Two's complement basically works by the very left-most bit signifies a negative number and is taken as a negative value. All other 1 bits are added to this number. For example:orm

1010 => (-8 +0 +2 +0) => -6
1111 => (-8 +4 +2 +1) => -1htm

又琢磨了一下子,才搞明白爲啥補碼這麼反直覺。blog

「二補碼」只能腦補,或者用代碼打印腦補的內容。

在JavaScript裏,若是用number.toString(2),結果是這樣:

Decimal:   5  |  Binary: 00000000000000000000000000000101
Decimal:   4  |  Binary: 00000000000000000000000000000100
Decimal:   3  |  Binary: 00000000000000000000000000000011
Decimal:   2  |  Binary: 00000000000000000000000000000010
Decimal:   1  |  Binary: 00000000000000000000000000000001
Decimal:   0  |  Binary: 00000000000000000000000000000000
Decimal:  -0  |  Binary: 00000000000000000000000000000000
Decimal:  -1  |  Binary: 000000000000000000000000000000-1
Decimal:  -2  |  Binary: 00000000000000000000000000000-10
Decimal:  -3  |  Binary: 00000000000000000000000000000-11
Decimal:  -4  |  Binary: 0000000000000000000000000000-100
Decimal:  -5  |  Binary: 0000000000000000000000000000-101

這個結果符合直覺,但加法器的實現只會使用二補碼,下面是加法器實際使用的「二補碼」:

Decimal:   5  |  Binary: 00000000000000000000000000000101
Decimal:   4  |  Binary: 00000000000000000000000000000100
Decimal:   3  |  Binary: 00000000000000000000000000000011
Decimal:   2  |  Binary: 00000000000000000000000000000010
Decimal:   1  |  Binary: 00000000000000000000000000000001
Decimal:   0  |  Binary: 00000000000000000000000000000000
Decimal:  -0  |  Binary: 00000000000000000000000000000000
Decimal:  -1  |  Binary: 11111111111111111111111111111111
Decimal:  -2  |  Binary: 11111111111111111111111111111110
Decimal:  -3  |  Binary: 11111111111111111111111111111101
Decimal:  -4  |  Binary: 11111111111111111111111111111100
Decimal:  -5  |  Binary: 11111111111111111111111111111011

理解了二補碼,再來看-22怎麼被補成21的:

Decimal: -22  |  Binary: 11111111111111111111111111101010
->
Decimal:  21  |  Binary: 00000000000000000000000000010101

Python對此解釋得更直接:

~ x
Returns the complement of x - the number you get by switching each 1 for a 0 and each 0 for a 1.
This is the same as -x - 1.

我連補碼都沒鬧明白,居然過了關還Score top 30%,可見其餘人都沒做弊,我真是無恥的程序員。

寫了半天,一言以蔽之:

~x 至關於調用

function twosComplement(x){
    return 0 -x - 1;
}

參考連接:

相關文章
相關標籤/搜索