我来了……

~(按位非), &(与), |(或)以及^(异或)的二进制使用

基础知识:

&位与:与(x&y)两二进制上下比较只有位值都为1时才取1,否则取0

例如:14&15  (14  二进制  1110

15 二进制         1111

&与的结果          1110  —-》结果14)

|位或:与(x|y)两二进制上下比较只有位值都为0时才取0,否则取1

14|15  (14  二进制  1110

15 二进制      1111

|与的结果       1111 —-》结果15)

^位异或:与(x^y)两二进制上下比较只有位不相等时才取1,否则取零

14^15  (14  二进制  1110

15    二进制   1111

^与的结果      0001 —-》结果1)

~位非:某个数值的按位非操作,可以简单的理解为该值取负值后减1,例如:
~5 = -5-1 = -6
~-5 = 5-1 = 4
~4 = -4-1 = -5

原理:

二进制数的负数是取该二进制数的补码,然后+1。
二进制数,最高位为0表示正数,最高位为1表示负数。(最高位分不同情况存储不一样)
5的二进制表示:00000101 (假设最高位为8位)
补码:11111010
-5:11111011

(~)按位非操作其实就是取补码的过程,也就是上述求该值负数的逆过程,所以可以简单的理解为该值取负值后减1。

5的补码就是5,那么5+1 = -5,所以~5 = -5-1 = -6

应用:

1、indexOf()

判断数组或者字符串中是否存在某个元素,一般使用indexOf()如下:

if(str.indexOf(query) != -1) {}
if(str.indexOf(query) >= 0) {}

现在可以更加清爽和高端的写成:

if(~str.indexOf(query)) {}

原理:
不存在返回-1,~-1 = 0 ,大于-1的值,0,1,2,3 … 按位非的值-1,-2,-3,-4…都不等于0

ps: 这种写法可不仅仅的B格高这么简单,位运算相对于比较运算符效率高,对于一次运算本身来说,可能相差无几,但在循环次数过大,比如超过了10000000次,效率就会有差距。

2、~~value的使用

对于浮点数,~~value可以代替parseInt(value),而且前者效率更高些。~~对浮点数取整,这个忽略了一个东西没讲,js在对浮点数取反时会先做一个隐式类型转换转成整数,再一次取反后,自然就变回原值的取整结果了。

parseInt(-2.99) //-2
~~(-2.99) //-2

3、一道算法题

找出数组中出现奇数次的元素。比如array=[1,2,3,4,3,2,1,5,5,6,6,6,6], 这里面4出现了一次。这种题目也可以采用循环来做,但是时间复杂度就是o(n^2), 而用异或就很简单了。时间复杂度o(n), 空间复杂度 o(1)

function getOddNumber( A ){
    let k = A[0]
    A.forEach(item=>{
        k = k ^ item
    })
    return k
}

未经允许不得转载:前端学堂fed123 » ~(按位非), &(与), |(或)以及^(异或)的二进制使用

分享到:更多 ()