Java位运算及补码存储

一、原码形式存储

首先,原码是站在用户角度的,是原始的二进制!

求原码步骤:
用户的数字分为正负数,需要有一位存储符号
最高位为符号位:0为正,1为负
左边是高位,右边是低位
由原码的计算方式可以发现源码存储会引发2个问题:

(1)0有两个存储方式

我们以char型(占1字节,8位)为例(下同):

+0:    0000 0000

-0:    1000 0000

不难发现+0和-0的原码是不一样的,而在计算过程中,+0和-0是没有任何区别的。

(2)正数和负数相加,结果不正确(计算机只会加)

1 - 1 =1 + (-1)

 1:  0000 0001

-1:  1000 0001

 1000 0010  =  -2

很显然1-1=0,而用原码进行计算得出的结果却相差甚远!

二、反码形式存储

既然原码不适合作为计算机的存储方式,人们在解决这个问题的过程中又提出了反码的概念

求反码步骤:
符号为不变,其他位取反
注意:正数原码、反码一样 !

接下来我们检验一下1 - 1:

  1:    0000 0001

 -1:    1111 1110

1111 1111 -> 1000 000 ( 转换为原码,因为原码是站在用户角度的 )  =  -0

不难可能出反码已经解决的正负数相加结果不正确的问题

然后我们再检验+0、-0

+0  0000 0000

-0   1111 1111

由此看出,反码并没有解决0有两种形式的问题

三、补码形式存储

在反码的基础上,人们有提出了补码的概念

求补码:补码为其反码+1
注意:正数的原码、反码、补码都一样!

接下来我们对补码存储进行验证:

+0: 0000 0000

-0: 
原码:  1000 0000
反码:  1111 1111
补码: 10000 0000(char占1字节八位,最高位丢弃)= 0000 0000

可以看出补码解决了+0 -0不一样的问题

+1: 0000 0001

-1: 1111 1111 

1 0000 0000(最高位丢弃)= 0000 0000 = 0

那么补码也解决了正负数相加结果不正确的问题!

四、总结:

补码是在原码的基础上为了适应计算机运算一步一步完善而来,原码和反码存储都有一定的弊端,因此计算机采用补码存储!

Java提供的位运算符有:
左移( << )、右移( >> ) 、无符号右移( >>> ) 、位与( & ) 、位或( | )、位非( ~ )、位异或( ^ ),除了位非( ~ )是一元操作符外,其它的都是二元操作符。

左移( << )

将5左移2位:5<<2

首先会将5转为2进制表示形式 ( java中,整数默认就是int类型,也就是32位):

0000 0000 0000 0000 0000 0000 0000 0101           然后左移2位后,低位补0:

0000 0000 0000 0000 0000 0000 0001 0100           换算成10进制为20

右移( >> )

5>>2
还是先将5转为2进制表示形式:

0000 0000 0000 0000 0000 0000 0000 0101 然后右移2位,高位补0

0000 0000 0000 0000 0000 0000 0000 0001

无符号右移( >>> )

我们知道Java中int类型占32位,既可以一个正数,也可以表示负数。其中最高位是符号位,正数为0,负数为1

例如 -5换算成二进制后为(补码形式:原码取反 + 1):

1111 1111 1111 1111 1111 1111 1111 1011   

我们分别对5进行右移3位、 -5进行右移3位和无符号右移3位:

5>>3 结果是0
-5>>3 结果是-1
-5>>>3 结果是536870911

5换算成二进制: 0000 0000 0000 0000 0000 0000 0000 0101

5右移3位后结果为0,0的二进制为: 0000 0000 0000 0000 0000 0000 0000 0000     (高位补0)

 -5换算成二进制: 1111 1111 1111 1111 1111 1111 1111 1011

-5右移3位后结果为-1,-1的二进制为: 1111 1111 1111 1111 1111 1111 1111 1111   (高位补1)

-5无符号右移3位后的结果 536870911 换算成二进制: 0001 1111 1111 1111 1111 1111 1111 1111   (高位补0)

通过其结果转换成二进制后,我们可以发现,正数右移,高位用0补,负数右移,高位用1补,当负数使用无符号右移时,用0进行补位(自然而然的,就由负数变成了正数了)

注意:这里说的是右移,高位补位的情况。正数或者负数左移,低位都是用0补。

位与( & )

5 & 3

5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101

3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011

-------------------------------------------------------------------------------------

1转换为二进制:0000 0000 0000 0000 0000 0000 0000 0001

位与:第一个操作数的的第n位于第二个操作数的第n位如果都是1,那么结果的第n为也为1,否则为0

位或( | )

5 | 3

5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101

3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011

-------------------------------------------------------------------------------------

7转换为二进制:0000 0000 0000 0000 0000 0000 0000 0111

位或操作:第一个操作数的的第n位于第二个操作数的第n位 只要有一个是1,那么结果的第n为也为1,否则为0

位异或( ^ )

5 ^ 3
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101

3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011

-------------------------------------------------------------------------------------
6转换为二进制:0000 0000 0000 0000 0000 0000 0000 0110

位异或:第一个操作数的的第n位于第二个操作数的第n位 相反,那么结果的第n为也为1,否则为0

位非( ~ )

~5
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
-------------------------------------------------------------------------------------

-6转换为二进制:1111 1111 1111 1111 1111 1111 1111 1010

位非:操作数的第n位为1,那么结果的第n位为0,反之。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值