关于java的位运算

首先自己总结几句话:

1. 数据在java中是以补码的形式对负数进行存储的,将数(正数或负数)从二进制码还原回来的步骤为:

a.最高位为0,则为正数,直接转成十进制即可,结束;

b.最高位为1,则为负数,先记下符号为“-”;

c.接着计算出绝对值,即对所有位都取反(包括符号位),然后加1,最后转为十进制,即为绝对值。

d.将该绝对值放在“-”右侧,即得到负数的值了。

2.java中char占2个字节

3. java中int占4个字节,取值范围是:-2^31~2^31-1 即:-2147483648~2147483647


以下是转载内容:

为什么一个值为127的byte数,加1后为-128?

这是因为整数在内存中使用的是补码的形式表示,最高位是符号位,0表示正数,1表示负数:
例如一个8位的整数
正数的补码:为这个数的2进制码,例如3:0000 0101
负数的补码:为这个负数的绝对值的2进制码,取反加1,例如-3:
   a: 3的2进制码取反为: 1111 1010
   b: 加1:1111 1011
   c: 所以-3的补码是:1111 1011


从补码计算这个数:
从一个正数的补码计算这个正数,例如0000 0101:因为符号位是0,所以是正数,所以直接计算这个正数就行了,所以结果是 3


从一个负数的补码计算这个负数,例如-3:1111 1011:
   a: 因为符号位(最高位)为1,所以表示这个数是负数
   b: 用补码取反加1为这个负数的绝对值整数值:0000 0100 + 1 => 0000 0101 => 3
   c: 所以1111 1011的值为-3


例如:
   byte b = 127;
   b = (byte) (b + 1);
最后b的值是多少?
   127的二进制为: 0111 1111
   127+1则为:0111 1111 + 1 = 1000 0000
所以当计算1000 0000的值时,
   a: 最高位为1,所以是负数
   b: 取反加1:0111 1111 + 1 = 1000 0000
   c: 计算1000 0000的值:128
   d: 结果:128的负值,所以为-128,即byte类型的127加1的值为-128

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

java 定义的位运算(bitwise operators )直接对整数类型的位进行操作,这些整数类型包括long,int,short,char,and byte 。
   所有的整数类型(除了char 类型之外)都是有符号的整数。这意味着他们既能表示正数,又能表示负数。Java 使用采用补码来表示负数。
   为什么采用补码吗?这是考虑到零的交叉(zero crossing )问题。
   原码:
   将最高位作为符号位(以0代表正,1代表负),其余各位代表数值本身的绝对值(以二进制表示)。这个时候有一个问题:表示0的时候正0和负0表示并不一样,所以在计算机中没有采用原码的表示形式。
   反码:
   一个数如果为正,则它的反码与原码相同;一个数如果为负,则符号位为1,其余各位是对原码取反。问题和上面一样的。所以,计算机中也没有采用反码来表示数字。
   补码:
   一个数如果为正,则它的原码、反码、补码相同;一个数如果为负,则符号位为1,其余各位是对原码取反,然后再加1。也就是通过将与其对应的正数的二进制代码取反(即将1变成0,将0变成1),然后对其结果加1。例如,-42就是通过将42的二进制代码的各个位取反,即对00101010 取反得到11010101 ,然后再加1,得到11010110 ,即-42 。要对一个负数解码,首先对其所有的位取反,然后加1。例如-42,或11010110 取反后为00101001 ,或41,然后加1,这样就得到了42。
   在计算机中,如果我们用1个字节表示一个数,一个字节有8位,超过8位就进1,在内存中情况为:1 00000000。进位1被丢弃。这种情况,我们叫溢出。在计算机中,假定byte 类型的值零为0000 0000,反码为1111 1111 补码为1 0000 0000,在计算-0的补码的时候因为溢出,导致-0和+0是一样的表示,所以计算机中采用补码的形式表示数字。
数的最大值和最小值:由于最高位为符号位,所以最大值和最小值时要去掉最高位。如一个byte为8位.最大值为0111 1111 ,即 (2的7次方) -1 = 127.最小值为1000 0000,即-( 2的7次方) =-128。char为无符号数,没有符号位,所以最小值为0,最大值为1111 1111 1111 1111 ,即(2的16次方) -1。

移位运算符
包括:
“>> 右移,高位补符号位”;
“>>> 无符号右移,高位补0”;
“<< 左移”;

例子:
-5>>3=-1
1111 1111 1111 1111 1111 1111 1111 1011
1111 1111 1111 1111 1111 1111 1111 1111
其结果与 Math.floor((double)-5/(2*2*2)) 完全相同。

-5<<3=-40
1111 1111 1111 1111 1111 1111 1111 1011
1111 1111 1111 1111 1111 1111 1101 1000
其结果与 -5*2*2*2 完全相同。

5>>3=0
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0000
其结果与 5/(2*2*2) 完全相同。

5<<3=40
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0010 1000
其结果与 5*2*2*2 完全相同。

-5>>>3=536870911 
1111 1111 1111 1111 1111 1111 1111 1011
0001 1111 1111 1111 1111 1111 1111 1111

无论正数、负数,它们的右移、左移、无符号右移 32 位都是其本身,比如 -5<<32=-5、-5>>32=-5、-5>>>32=-5。
一个有趣的现象是,把 1 左移 31 位再右移 31 位,其结果为 -1。
0000 0000 0000 0000 0000 0000 0000 0001
1000 0000 0000 0000 0000 0000 0000 0000
1111 1111 1111 1111 1111 1111 1111 1111

位逻辑运算符
包括:
& 与;
| 或;
~ 非(也叫做求反);
^ 异或

“& 与”、“| 或”、“~ 非”是基本逻辑运算,由此可以演变出“与非”、“或非”、“与或非”复合逻辑运算。“^ 异或”是一种特殊的逻辑运算,对它求反可以得到“同或”,所以“同或”逻辑也叫“异或非”逻辑。

例子:
5&3=1
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0001

-5&3=1
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0011

5|3=7
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0111

-5|3=-5
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
1111 1111 1111 1111 1111 1111 1111 1011

~5=-6
0000 0000 0000 0000 0000 0000 0000 0101
1111 1111 1111 1111 1111 1111 1111 1010

~-5=4
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0100

5^3=6
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0110

-5^3=-8
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
1111 1111 1111 1111 1111 1111 1111 1000

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值