位运算的黑科技

作者: l_sivan | 来源:发表于2017-07-06 16:57 被阅读286次

    最近在学NodeJs,然后练手做项目的时候想用下位运算,需求是除2舍小数位,于是想像Java一样,直接除2,发现并不行

        console.log(5/2);
        sivan@sivan-All-Series:~/workspace/nodejs/interesting_book$ node h.js
        2.5
    

    想了下发现很正常,因为JavaScript是弱数据语言,全部的变量都可以用一个var来声明的,所以结果的表现是浮点型,确实很正常。
    于是换了一种方式,之间看Java的部分源码看到位运算的相关操作(后面会提),所以在这也试下位运算

        console.log(5/2>>1/2);
        sivan@sivan-All-Series:~/workspace/nodejs/interesting_book$ node h.js
        2
    

    结果一试就不得了了,居然还真的试出来了
    而在js的运算符中,算术运算符的优先级是大于移位运算符的,也就是上面的代码可以换成这样

        console.log(2.5 >> 0.5);
        sivan@sivan-All-Series:~/workspace/nodejs/interesting_book$ node h.js
        2
    

    而结果确实一样,觉得很黑科技,居然还能用浮点数做移位运算,右移0.5位?这么黑科技的,于是这个时候,去Java上尝试了一下


    Java下的尝试

    这边就很正常啦,因为Java里面,整数之间进行运算,得到的数还是整数,也就是上面的图片实际上相当于(2 >> 0)
    于是测试下


    换成浮点型 换成整型
    可见确实如同猜测一样
    于是,结合Java里出现的情况,对JS中的情况做了个猜测,js在有算术运算和移位运算同时存在的情况下,会将算术运算的结果转成整型再运算
    下面验证下猜测
        console.log(5/2>>1/2);
        console.log(2.5 >> 0.5);
        console.log(5/2 >> 0);
        console.log(2 >> 1/2);
        console.log(5.9/2 >> 0);
        console.log(2 >> 0);
    

    如无意外,这一批的log的结果,都会是2

        sivan@sivan-All-Series:~/workspace/nodejs/interesting_book$ node h.js
        2
        2
        2
        2  
        2
        2
    

    结果确实如同预料般。

    那这个位运算有啥用呢?

    首先
    哈哈哈,起码知道,在JS中想得到除以某个数舍小数位,只要右移或者左移0位就行了,像console.log(5/2 >> 0);---->2这样。
    除了这个发现之外,其实位运算确实挺方便的,比如
    想要放大或者缩小2的N次幂的倍数,只要左移或者右移N位就行了

    1位是为2的1次幂
    移几位这个可能会迷糊,其实联想下十进制就行了,500右移一位变成50,缩小了10倍,右移两位变成5,缩小了100倍也就是10的2次幂,所以无论什么进制都一样,移动N位,就变化进制的N次幂
    其次还有一个,如何快速得到某个数最接近的偏大2的次幂数,比如15--16,16--16,17--32
    答案就在HashMap的源码

    重点是n |= n >>> N这几行代码,画个图就懂了

    image.png
    因为进行了多次|=运算的运算,所以可以确保从最高位到最低位都是1,也就是值为2的N次方-1
    其中因为java中int的长度为32为,所以有n |= n >>> 16;,这样就能确保数很大的时候都能每一位都做过|=运算

    总结

    其实位运算的骚操作还有很多,只不过水平有限,计算机组成原理学的也不怎么样,所以这些其实也只是小打小闹。

    水平有限,难免有错,还请诸君指正。

    相关文章

      网友评论

        本文标题:位运算的黑科技

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