java 位运算整理_关于java位运算符&,~,^,|,的整理(包含二进制与十进制的转换)

要讲java一些奇奇怪怪的运算符号之前,必须先了解二进制,因为这些看不懂的运算符都是基于二进制运算的

计算机里二进制的运算,往往比十进制运算来的快。

首先了解下转换规则(相互转换):

转码之前,有一些名词概念:

1、原码

一个正数,按照绝对值大小转换成二进制数,称为原码

2、反码

将二进制数按位取反,所得的新二进制数称为原二进制数的反码

其实就是把原码中的0变为1,1变为0

例如:0000 0101 和1111 1010就是互为反码

3、补码

在反码的基础上加1称为补码,一般在算负数的时候会用到

十进制转二进制:

1、正整数转换二进制

2、负整数转换二进制

3、小数转换二进制

重点掌握前面两个:

1、正整数转换二进制

除二取余,然后倒序排列,高位补零。

如下图:三步操作(字丑勿喷)

99b8414b86e1387e95874eda0d1354c6.png

2、负整数转换二进制

先将对应的正整数转换成二进制

对二进制取反,这边有个不一样的地方,原来那个正数的补位都是0,但是你取反了,那就证明负数补位的时候,要补1

然后对结果再加1(这里的1,是十进制的1,但是十进制的1对应的二进制就是00000001)

如下图:

a343043d7a0d17f8dbd0b895274f22cd.png

3、小数转化二进制

先对小数部分*2,乘到小数部分为0

然后再对整数部分计算

最后合起来

如下图:

d635ece6d6697528389f0a6aaa5511c0.png

二进制转十进制:

这里会有两种情况,有符号数,和无符号数

1、无符号数的话就是直接转换成正整数

如下图:

d4daded47923362483e05b0177556340.png

2、有符号数的话,就把第一个数字看成符号,1就是负数,0就是正数

1)如果是正数,那就是第一位不用做计算,把后面的7位拿起来计算,

比如0111 1111 结果就是127

2)如果是负数,那算法就是先对结果(这个结果是补码)减1获得反码,然后取反(获得原码),然后计算,跟负十进制的数转换成二进制的数的操作是相反的

比如1111 1111,结果就是-1

转换过程:1111 1111 -1 = 1111 1110

取反:1111 1110 =》 0000 0001

转换:1*2的0次方=1,那因为我们一开始就定义它为负数,所以就是-1

======================================华丽的分割线============================================

明白了上面的相互转换之后

就开始来理解java中一些奇特的符号:

1、&(按位与)

2、|(按位或)

3、^(按位异或)

4、~ (按位取反)

5、>> (右移运算符)

6、<< (左移运算符)

这些就是java中对二进制数字的计算,别的语言应该还有些其他的符号

本人水平有限所以。。。。

1、& 与

规则:先将两个数字转换为二进制,然后每一位进行匹配

只有当两个位置上都是1的时候,才会返回1

例子:9&129:100112:1100所以结果应该是:1000=》转换为十进制:8

这个符号也有个例子,在Hadoop的MapReduce中默认实现的HashPartitioner类中的分区方法

public int getPartition(K2 key, V2 value, int numReduceTasks) {

return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;

}

就是使用这个符号。

2、| 或

规则:先将两个数字转换为二进制,然后每一位进行匹配

两个位只要有一个为1,那么结果就是1,否则就为0。

例子:9|129:100112:1100

所以结果应该是:1101=》转换为十进制:13

3、^ 异或

规则:先将两个数字转换为二进制,然后每一位进行匹配

两个操作数的位,相同则结果为0,不同则结果为1。

0 ^ 1 =1,1 ^ 1 = 0,0 ^ 0 = 0,1 ^ 0 = 1

例子:9^129:100112:1100

所以结果应该是:0101=》转换为十进制:5

4、~ 取反

规则:这个是对一个数字的操作

先将这个数字转换为二进制

然后每个位上的数字,0变成1,1变成0

例子:~9

9:1001

~9:0110

所以结果应该是0110=》转换为十进制:6

呵呵,你自己试试,答案是错的。。不是6,答案是-10

为什么?

先说一个概念int类型是4字节,1字节是8位,所以int类型有32位

然后,9的值是1001,其实你全部写出来应该是0000 0000 000...(前面有28个0)然后1001

所以对9取反,不能简单的写成0110,因为0110代表的是0000 0000 000...(前面有28个0)然后0110

~9:1111 1111 1111 1111 1111 1111 1111 0110

接着你可以在代码中试试:

String i = Integer.toBinaryString(-10);

System.out.println(i);

System.out.println(i.length());

打印出来的就是:

11111111111111111111111111110110

32

结论:所以这里就要说到,在上文中提到的二进制的有符号数和无符号数再重新阐述一次:简单来说,例如byte长度是8位,无符号数的情况下,1111 1111 =》255

有符号数的情况下,因为最高位1代表负号,0代表正号,所以 0111 1111 =》127,所以1000 0000 =》-128

所以你还记得byte类型能表示的长度是-128---127吗,就是这个原因那么在java中几乎所有的正数取反,会得到负数,负数取反会得到正数!比如1000 0001 这个二进制的有符号数,他代表的值就是-127所以这是取反操作的一个坑,也是不少网络给出的什么二进制转换器输入1000 0000得到的值为128的原因(因为他识别成无符号二进制数字)

如果你还不太懂,而且又想继续了解的话:http://www..com/ASPNET2008/archive/2009/04/29/1446471.html

这篇别人的文章,应该可以帮到你,作者我也不知道是谁(因为他也是转载的),如对原作者有所冒犯,实在抱歉,请给我留言,我标注作者!!

5、>> (右移运算符)和<< (左移运算符)

这两个东西,放在一起记录,是因为这两个操作是一样的,就是一个位移操作

1、举例1、12>>2

操作:先将12转换为二进制 ==》1100然后把整体向右移动两位 ==》0011最后转换为十进制 ==》 1*2的0次方+1*2的1次方=3所以答案:3

2、举例2、12<<2

操作:

先将12转换为二进制 ==》1100然后把整体向左移动两位 ==》110000最后转换为十进制 ==》 1*2的4次方+1*2的5次方=48所以答案:3结论:所以也能简单的理解为>>3就是原来的数字除以2的3次方,<<3就是乘以2的3次方

好的,本人菜鸟一只,整理就到这里,如果还有什么疑问,可以给我留言,如果有说的不对的地方,请各路大神指出!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值