java里面的 位运算_Java 里面的位运算总结

在进行Java位运算之前,首先需要了解一下在计算机中原码,补码,还有反码的知识。

原码表示法是机器数的一种简单的表示法。

其符号位用0表示正号,用:表示负号,数值一般用二进制形式表示。

机器数的反码可由原码得到。如果机器数是正数,则该机器数的反码与原码一样;

如果机器数是负数,则该机器数的反码是对它的原码(符号位除外)各位取反而得到的。

机器数的补码可由原码得到。如果机器数是正数,则该机器数的补码与原码一样;

如果机器数是负数,则该机器数的补码是对它的原码(除符号位外)各位取反,并在未位加1而得到的。

因为在电脑中存储数值都是用补码来进行存储的,所以对负数的计算首先要先算出它的补码值

下面对java的一些位运算符进行实例计算

首先是运算符分为 & | ~ ^ >> << >>>

意义分别为 位与’&’,位或’|’,位非’~’,位异或’^’,右移’>>’,左移’<>>’

其中位与运算是二者为1时才为1,否则为0

位或运算为两者有一个为1时则为1,否则为0

位非运算,0转换成1,1转换成0,首先高位符号位从0转为1

异或运算为两者都相同时则为0,否则为1

int a=129;//10000001

int b=128;//10000000

System.out.println("位与运算"+(a&b));//位与运算时两者为1时才为1,否则为0 结果为 1000 0000=128

System.out.println("位或运算"+(a|b));//位或运算为两者有一个为1时则为1,否则为0,结果为 1000 0001=129

System.out.println("位非运算"+(~b));//位非运算,0转换成1,1转换成0,首先高位符号位从0转为1

//结果为1111 1111 1111 1111 1111 1111 1111 0111 1111 对这个数进行取反

//结果为1000 0000 0000 0000 0000 0000 0000 1000 0000

// 加1后结果 1000 0000 0000 0000 0000 0000 0000 1000 0001

//答案为-129

System.out.println("异或运算"+(a^b));//异或运算为两者都相同时则为0,否则为1 结果为 00000001=1 运行结果为: 位与运算=128

位或运算=129

位非运算=-129

异或运算=1

下面对符号左移,符号右移,无符号右移进行描述(java中没有无符号左移)

负数右移时左边补1,正数右移时左边补0,无符号右移时无论是正数还是负数均左边补0。

int c=128;//1000 0000

int d=4;

System.out.println("符号右移="+(c>>d));

//右移四位相当于除以2的4次方,相当于128/16=8,实际上为1000 0000

// 0000 0000 0000 0000 0000 0000 1000 0000

//右移四位结果为 0000 0000 0000 0000 0000 0000 0000 1000 结果为8

System.out.println("符号左移="+(c<

//左移四位相当于乘上2的4次方,相当于128*16=2048

// 0000 0000 0000 0000 0000 0000 1000 0000

//左移四位结果为 0000 0000 0000 0000 0000 1000 0000 0000=2的11次方=2048

System.out.println("无符号右移="+(c>>>d));

//右移四位相当于除以2的4次方,相当于128/16=8,实际上为1000 0000

// 0000 0000 0000 0000 0000 0000 1000 0000

//右移四位结果为 0000 0000 0000 0000 0000 0000 0000 1000 结果为8

得到结果为

符号右移=8

符号左移=2048

无符号右移=8

下面对负数进行右移左移及无符号右移进行计算 int m=-128;

int n=4;

System.out.println("符号右移="+(m>>n));

// 1000 0000 0000 0000 0000 0000 1000 0000 -128的原码

// 1111 1111 1111 1111 1111 1111 0111 1111 -128的反码

// 1111 1111 1111 1111 1111 1111 1000 0000 -128的补码

// 1111 1111 1111 1111 1111 1111 1111 1000 负数右移时左边补1,正数右移时左边补0,这里重新取补码得到答案

// 1000 0000 0000 0000 0000 0000 0000 0111 取反得

// 1000 0000 0000 0000 0000 0000 0000 1000 取补得结果为-8

System.out.println("符号左移="+(m<

// 1111 1111 1111 1111 1111 1111 1000 0000 -128的补码

// 1111 1111 1111 1111 1111 1000 0000 0000 左移时右边补0,符号位不变

// 1000 0000 0000 0000 0000 0111 1111 1111 取反时符号位不变

// 1000 0000 0000 0000 0000 1000 0000 0000 取补码为 -2048

System.out.println("无符号右移="+(m>>>n));

//无符号右移时左侧只补0

//1111 1111 1111 1111 1111 1111 1000 0000 -128的补码

//0000 1111 1111 1111 1111 1111 1111 1000 直接得出答案

符号右移=-8

符号左移=-2048

无符号右移=268435448

这里要重新重点强调一下,正数的 原码,反码和补码全部相同。所以算出答案后直接转换成正数值

假如右移的是负数位的情况也有

在java中对int型的右移则是让这个负数位和0b11111进行位与运算,对long类型的则是和0b111111进行位与运算

这里参考于:Chapter 15. Expressions

If the promoted type of the left-hand operand is int, then only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator& (§15.22.1)

with the mask value 0x1f (0b11111). The shift distance actually used is therefore always in the range 0 to 31, inclusive.

If the promoted type of the left-hand operand is long, then only the six lowest-order bits of the right-hand

operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x3f (0b111111). The shift distance actually used is therefore always in the

range 0 to 63, inclusive.

int k=2048;

int l=-30;

System.out.println(k>>l);

//位移负数位

//题目效果为 2048>>(-30&0b11111)

//-30的原码为1000 0000 0000 0000 0000 0000 0001 1110

//-30的反码为1111 1111 1111 1111 1111 1111 1110 0001

//-30的补码为1111 1111 1111 1111 1111 1111 1110 0010

// 0000 0000 0000 0000 0000 0000 0001

1111 int型取后5位,long型后6位均为1

// 0000 0000 0000 0000 0000 0000 0000 0010 进行位与运算后得到结果为2

//上面相当于效果为2048 右移两位 得到答案为 512

最终结果得到为512

Older Hello World

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值