一,Java 位运算 java
1.表示方法: post
在Java语言中,二进制数使用补码表示,最高位为符号位,正数的符号位为0,负数为1。补码的表示须要知足以下要求。 spa
(1)正数的最高位为0,其他各位表明数值自己(二进制数)。 对象
(2)对于负数,经过对该数绝对值的补码按位取反,再对整个数加1。 blog
2.位运算符 编译器
位运算表达式由操做数和位运算符组成,实现对整数类型的二进制数进行位运算。位运算符能够分为逻辑运算符(包括~、&、|和^)及移位运算符(包括>>、<<和>>>)。 编译
1)左移位运算符(<<)能将运算符左边的运算对象向左移动运算符右侧指定的位数(在低位补0)。 class
2)“有符号”右移位运算符(>>)则将运算符左边的运算对象向右移动运算符右侧指定的位数。 “有符号”右移位运算符使用了“符号扩展”:若值为正,则在高位插入0;若值为负,则在高位插入1。变量
3)Java也添加了一种“无符号”右移位运算符(>>>),它使用了“零扩展”:不管正负,都在高位插入0。这一运算符是C或C++没有的。 扩展
4)若对char,byte或者short进行移位处理,那么在移位进行以前,它们会自动转换成一个int。 只有右侧的5个低位才会用到。这样可防止咱们在一个int数里移动不切实际的位数。 若对一个long值进行处理,最后获得的结果也是long。此时只会用到右侧的6个低位,防止移动超过long值里现成的位数。 但在进行“无符号”右移位时,也可能遇到一个问题。若对byte或short值进行右移位运算,获得的可能不是正确的结果(Java 1.0和Java 1.1特别突出)。 它们会自动转换成int类型,并进行右移位。但“零扩展”不会发生,因此在那些状况下会获得-1的结果。
在进行位运算时,须要注意如下几点。
(1)>>>和>>的区别是:在执行运算时,>>>运算符的操做数高位补0,而>>运算符的操做数高位移入原来高位的值。
(2)右移一位至关于除以2,左移一位(在不溢出的状况下)至关于乘以2;移位运算速度高于乘除运算。
(3)若进行位逻辑运算的两个操做数的数据长度不相同,则返回值应该是数据长度较长的数据类型。
(4)按位异或能够不使用临时变量完成两个值的交换,也可使某个整型数的特定位的值翻转。
(5)按位与运算能够用来屏蔽特定的位,也能够用来取某个数型数中某些特定的位。
(6)按位或运算能够用来对某个整型数的特定位的值置l。
3.位运算符的优先级
~的优先级最高,其次是<<、>>和>>>,再次是&,而后是^,优先级最低的是|。
二, 按位异或运算符^
参与运算的两个值,若是两个相应位相同,则结果为0,不然为1。即:0^0=0, 1^0=1, 0^1=1, 1^1=0
例如:10100001^00010001=10110000
0^0=0,0^1=1 0异或任何数=任何数
1^0=1,1^1=0 1异或任何数-任何数取反
任何数异或本身=把本身置0
(1)按位异或能够用来使某些特定的位翻转,如对数10100001的第2位和第3位翻转,能够将数与00000110进行按位异或运算。 10100001^00000110=10100111 //1010 0001 ^ 0x06 = 1010 0001 ^ 6
(2)经过按位异或运算,能够实现两个值的交换,而没必要使用临时变量。
例如交换两个整数a,b的值,可经过下列语句实现:
a=10100001,b=00000110
a=a^b; //a=10100111
b=b^a; //b=10100001
a=a^b; //a=00000110
(3)异或运算符的特色是:数a两次异或同一个数b(a=a^b^b)仍然为原值a.
三,Java 中除了二进制的表示方法:
因为数据在计算机中的表示,最终以二进制的形式存在,因此有时候使用二进制,能够更直观地解决问题。
但,二进制数太长了。好比int 类型占用4个字节,32位。好比100,用int类型的二进制数表达将是:
0000 0000 0000 0000 0110 0100
面对这么长的数进行思考或操做,没有人会喜欢。所以,C,C++,以及java中 没有提供在代码直接写二进制数的方法。
八进制数的表达方法
如何表达一个八进制数呢?若是这个数是 876,咱们能够判定它不是八进制数,由于八进制数中不可能出7以上的阿拉伯数字。但若是这个数是12三、是567,或12345670,那么它是八进制数仍是10进制数,都有可能。
因此规定,一个数若是要指明它采用八进制,必须在它前面加上一个0,如:123是十进制,但0123则表示采用八进制。这就是八进制数的表达方法。 如今,对于一样一个数,好比是100,咱们在代码中能够用日常的10进制表达,例如在变量初始化时:
int a = 100;
咱们也能够这样写:
int a = 0144; //0144是八进制的100;一个10进制数如何转成8进制。
千万记住,用八进制表达时,你不能少了最前的那个0。不然计算机会统统当成10进制。不过,有一个地方使用八进制数时,却不能使用加0,那就是咱们前面学的用于表达字符的“转义符”表达法。
十六进制数的表达方法
若是不使用特殊的书写形式,16进制数也会和10进制相混。随便一个数:9876,就看不出它是16进制或10进制。
16进制数必须以 0x开头。好比 0x1表示一个16进制数。而1则表示一个十进制。另外如:0xff,0xFF,0X102A,等等。其中的x也也不区分大小写。(注意:0x中的0是数字0,而不是字母O)
如下是一些用法示例:
int a = 0x100F;
int b = 0x70 + a;
最后一点很重要,10进制数有正负之分,好比12表示正12,而-12表示负 12,;但8进制和16进制只能用来表达无符号的正整数,若是你在代码中里:-078,或者写:-0xF2,编译器并不把它当成一个负数。