程序员Java学习笔记

位运算的黑科技

2017-07-06  本文已影响286人  l_sivan

最近在学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;,这样就能确保数很大的时候都能每一位都做过|=运算

总结

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

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

上一篇下一篇

猜你喜欢

热点阅读