欢迎光临散文网 会员登陆 & 注册

JAVA 位运算

2021-04-20 15:55 作者:光耀三十洲  | 我要投稿

前言 :

为什么需要介绍下位运算呢?其实我是在发现不少性能代码都有不少位运算的身影,之前一直提到位运算的性能高,但是工作中业务码农过程用到的极少,一直没有用心去了解它,今天就来一起看看这家伙怎么这么牛!文章如果有什么不正确的地方,欢迎大家指出哈,感谢感谢.

● 十进制转二进制(正负数) ● 二进制加减法 ●  位运算符 ●  位移动运算符

十进制转二级制

位运算是二级制的事情,不过由于我们常常使用的是十位数的计算,先来重温下十进制转成二进制的方法。

方法: 给定的十进制数值除以二,记录余数(0 | 1),直到结束,将所得余数反着读,就是其二进制数值,同时这个值也称为原码。若是为负数时,其转成二进制方式为原码 -> 反码(原码的 0 变 1,1 变成 0) -> 补码(将反码 + 1)。

(1)正数十进制 29 转 成二进制数值 变成 11101 。

(2)负数 -29,得到原码 11101,转化反码得到 00010,再得到反码 00011,表示负数前面补 1,如需要获取 32 位二进制数据,则 -29的二进制为 1111 1111 1111 1111 1111 1111 1110 0011。

补充:小伙伴想要验证自己的计算答案可以利用JAVA 中,十进制转二进制的方式,(N 为此处的十进制数值) Integer.toBinaryString(N);可以输出转化二进制结果。二进制转十进制方式, 1100 转十进制,为 Integer.pase("1100",2);

二进制加减法

刚刚获取负数的时候,已经发现二进制也有加法计算哟,简单描述下加减法的过程,主要注意加法中 1+ 1 结果为 0,需要进一位,减法中, 0 - 1 需要借一位当成 2 计算,结果为 1 。

二进制篇旁括号内为其十进制的值。

加法: 0101 (5) + 1101 (13)

image.png

在运算过程中,从右往左逐位进行计算。

  • 1 + 1 = 0 ;进一位。

  • 0 + 0 +  1(进一位) = 1。

  • 1 + 1 = 0 ;进一位。

  • 0 + 1 +1(进一位)= 0 ;进一位。

  • 接下去没有数补上进一位的值,则结果为 1 0 0 1 0(18)。

减法:0101-  1101

image.png

运算过程:

  • 1 - 1 = 0;

  • 0 - 0 = 0;

  • 1 - 1 = 0;

  • 0 - 1 = -1 + 2 (借一位)= 1

  • 此处位置没有值啦,需要一直借下去 一直会是 1。 若是结果为 32 位,那么值就是 1111 1111 1111 1111 1111 1111 1111 1000(- 8);

位运算符

主要包含了四种位运算符:与( & )、非( ~ )、或( | )、异或( ^ )

计算方式,简单赘述,总结一下特点如下 ——

  • 与   ( & ):都是 1 ,才是 1。

  • 非   ( ~ ):0 变 1,1 变 0。

  • 或   ( | ):有 1 就是 1。

  • 异或 ( ^ ):相同为 0,不同为 1。

位移动运算符

主要包含三种 << (左移)、>> (右移)、>>>(无符号右移),看到这里符号,一开始面试题里面出现的,如何最快算出一个数乘以 8 的计算方式?答案就是: 数 << 3。因为计算机语言就是二进制呀,不管是 JAVA 还是其他的语言,最终都是转成二进制进行运算的,如果直接就是二进制的计算方式,不就不用转啦。

「因为移位指令占2个机器周期,而乘除法指令占4个机器周期。」

<< (左移) N: 把原有的值往左边移动 N 位,低位补充 N个 0,从计算上,是把原先的值乘以N个2,

1001 << 3 :

image.png

(右移)>> N: 此处就有了区分正负数,顶位为 0 则是正数,顶位为 1 则是负数。 把原有的值往右边移动 N 位,若是正数,高位需要补 0 ,若是负数,高位补 1。实际计算相当于除以 N 次 2。

image.png

(无符号右移)>>> 形同 >> (右移),不过不用管正负数了,高位一律补 0,就完事啦。

对比:

  • 1101 0101 >> 2  = 11110101

  • 1101 0101 >>> 2 = 00110101


作者:Solming
链接:https://juejin.cn/post/6952866830889254925
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


JAVA 位运算的评论 (共 条)

分享到微博请遵守国家法律