美文网首页
JS中按位取反运算符~及其它运算符

JS中按位取反运算符~及其它运算符

作者: LinDaiDai_霖呆呆 | 来源:发表于2020-05-09 18:31 被阅读0次

    ~按位取反运算符

    正常一个数字,例如12,或者-1-2

    如果我们对它们进行按位取反的话,结果会是这样:

    • ~1 = -2
    • ~2 = -3
    • ~-1 = 0
    • ~-2 = 1

    看不懂没关系,让我们来一步步看看实现的过程哈。

    在这里其实是分了正数和负数的,因为符号不同取反的过程也会不同。

    1.1 正数按位取反

    先让我们来看看正数的按位取反。

    比如先看看~1 = -2,过程如下:

    1. 十进制转为二进制原码

    首先将十进制的1转化为二进制原码为:0000 0001

    2. 二进制原码按位取反

    之后将原码按位取反:

    也就是将0000 0001 => 1111 1110

    (取反应该知道啥意思吧?就是0换成11换成0)

    3. 取反后的二进制转为原码

    再将取反后的二进制码转为原码二进制:

    也就是将1111 1110 => 1000 0010

    这里你估计看着都点懵了,当我们将取反后的二进制转为原码二进制的时候,其实是有以下两步的:

    1. 需要判断取反后的二进制的第一个位是不是1,这个第一位我们称之为符号位,如果是1的话就表示即将要转成的数是一个负数,如果是0的话表示即将要转的数是一个正数,这个符号位是不能动的;在这里我们可以看到1111 1110的第一位是1,所以表示即将要转的数是一个负数,同时我们不动它。
    2. 然后将除了第一位以外其它位数取反并+1。所以会有这么两个过程:
      • 1111 1110 => 1000 0001
      • 1000 0001 => 1000 0010 (这步是对上一步的结果+1,因为上一步的最后一个数是1,所以它再加上1就需要向前进一位了,因此变成了1000 0010)

    4. 将原码二进制转为十进制

    最后一步就是将我们前面得到的1000 0010这个二进制转化为十进制了。

    第一位符号位,是1,则表示是个负数,所以结果为-2

    OK👌,搞懂了这个步骤之后再让我们自己来转换一下~2 = -3吧:

    1. 0000 0010
    2. 1111 1101
    3. 1000 0011
    4. -3
    

    正数按位取反总结

    1. 十进制转为二进制原码
    2. 二进制原码按位取反
    3. 符号位保留,其余位取反+1
    4. 二进制原码转为十进制

    1.2 负数按位取反

    负数的按位取反和上面就有些不一样了,主要是第二步和第三步调换一下顺序:

    1. 十进制转为二进制原码
    2. 符号位保留,其余位取反+1
    3. 二进制原码按位取反
    4. 二进制原码转为十进制

    例如:~-1 =0的转换过程:

    1. 十进制转为二进制原码

    这步和正数按位取反是一样的:

    -1 => 1000 0001

    2. 符号位保留,其余位取反+1

    转换过程:

    • 1000 0001 => 1111 1110 (取反)
    • 1111 1110 => 1111 1111 (取反后 + 1)

    3. 二进制原码按位取反

    将刚刚得到的再进行按位取反:

    1111 1111 => 0000 0000

    4. 二进制原码转为十进制

    0000 0000 => 0

    OK👌,现在自己来转换一下~-2 = 1吧:

    1. 1000 0010
    2. 1111 1110
    3. 0000 0001
    4. 1
    

    这里没啥诀窍,关键就是要记住转换的过程然后不断的练习吧 😂。

    ~~双非按位取反运算符

    ~~它代表双非按位取反运算符,如果你想使用比Math.floor()更快的方法,那就是它了。它有这么两个特点:

    • 非数字取值为0,它具体的表现形式为:
    ~~null;      // => 0
    ~~undefined; // => 0
    ~~Infinity;  // => 0
    --NaN;       // => 0
    ~~0;         // => 0
    ~~{};        // => 0
    ~~[];        // => 0
    ~~(1/0);     // => 0
    ~~false;     // => 0
    ~~true;      // => 1
    

    对比与Number()的好处就是Number(undefined)会转换为NaN;但是使用~~能保证一直是数字。

    • 对于正数,它向下取整;对于负数,向上取整:
    console.log(~~1.3) // 1
    console.log(~~-1.3) // -1
    

    Math.floor()的不同,Math.floor()都是向下取整:

    console.log(Math.floor(1.3)) // 1
    console.log(Math.floor(-1.3)) // -2
    console.log(~~1.3) // 1
    console.log(~~-1.3) // -1
    

    |运算符

    通常用来取整,如:

    1.2|0  // 1
    1.8|0 // 1
    -1.2|0 // -1
    

    其它运算符

    类似的还有:

    <<左移,<<a 将a第一位丢弃,后七位尾部加0

    >>右移,>>a 将a末位丢弃,前七位开头加0

    & 或,a & b 将a和b中所有为1的位组成新值

    ^ 异,a ^ b 将a和b中ab不同的位组(即其中一个为0且另一个为1,则为1,两个都为0或都为1,则为0)成新值

    参考文章

    相关文章

      网友评论

          本文标题:JS中按位取反运算符~及其它运算符

          本文链接:https://www.haomeiwen.com/subject/ckllnhtx.html