您的位置:首页 > 编程语言 > Java开发

Java数据类型和位运算

2016-01-26 18:06 218 查看

一、数据类型




其中基本数据类型为:



注意:byte,short,char之间不会相互转换,他们三者在计算时首先转换为int类型。

其中 char 16位 2个字节

byte 8位1个字节, short 16位2个字节 , int 32位4个字节 , long 64位8个字节

float 32位 4个字节, double 64位8个字节

声明 long 型常量须后加 ‘l’ 或 ‘L’

二、位运算

1、位运算基本操作

1.1、移位运算符

移位运算符java移位运算符不外乎就这三种:<<(左移)、>>(带符号右移)和>>>(无符号右移)。

1)、 左移运算符

左移的规则只记住一点:丢弃最高位,0补最低位

如果移动的位数超过了该类型的最大位数,那么编译器会对移动的位数取模(取整)。

如对int型移动33位,实际上只移动了33/32=1位。4>>32与4>>0是等价的

当左移的运算数是int 类型时,每移动1位它的第31位就要被移出并且丢弃;

当左移的运算数是long 类型时,每移动1位它的第63位就要被移出并且丢弃。

当左移的运算数是byte 和short类型时,将自动把这些类型扩大为 int 型。(右移也一样)

数学意义

在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方

2)、右移运算符

右移的规则只记住一点:符号位不变,左边补上符号位

按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1

例如,如果要移走的值为负数,每一次右移都在左边补1,如果要移走的值为正数,每一次右移都在左边补0,这叫做符号位扩展(保留符号位)(sign extension ),在进行右移

操作时用来保持负数的符号。

数学意义:右移一位相当于除2,右移n位相当于除以2的n次方。

3)、无符号右移

无符号右移的规则只记住一点:忽略了符号位扩展,0补最高位

无符号右移运算符>>> 只是对32位和64位的值有意义

@Test
public void test(){
// 1、左移( << ):丢弃最高位,0补最低位
// 0000 0000 0000 0000 0000 0000 0000 0101 然后左移2位后,低位补0://
// 0000 0000 0000 0000 0000 0000 0001 0100 换算成10进制为20
System.out.println(5 << 2);// 运行结果是20
System.out.println(-5 << 2);// 运行结果是-20

// 2、右移( >> ): 符号位不变,左边补上符号位
// 0000 0000 0000 0000 0000 0000 0000 1011 然后右移2位,高位补0:
// 0000 0000 0000 0000 0000 0000 0000 0010
System.out.println(11 >> 2);// 运行结果是2
System.out.println(-11 >> 2);// 运行结果是-3

// 3、无符号右移( >>> ): 忽略了符号位扩展,0补最高位
// 例如 -5换算成二进制后为:0101 取反加1为1011
// 1111 1111 1111 1111 1111 1111 1111 1011
// 我们分别对5进行右移3位、 -5进行右移3位和无符号右移3位:
System.out.println(5 >> 3);// 结果是0
System.out.println(-5 >> 3);// 结果是-1
System.out.println(-5 >>> 3);// 结果是536870911
 }


1.2、位运算符

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

11转成二进制是:1011,7转成二进制为:0111。所以结果为:0011

System.out.println(11 & 7);// 结果为3

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

11转成二进制是:1011,7转成二进制为:0111。所以结果为:1111

System.out.println(11 | 7);// 结果为15

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

11转成二进制是:1011,7转成二进制为:0111。所以结果为:1100

System.out.println(5 ^ 3);//结果为12

4、位非( ~ ):操作数的第n位为1,那么结果的第n位为0,反之。(注:Java中正数的最高位为0,负数最高位为1,即最高位决定正负符

7转成二进制为:0111。所以结果为:1000

System.out.println(~5);// 结果为-8

2、位运算应用

1. 判断奇偶性,int型变量a是奇数还是偶数

(a&1) = 0 偶数

(a&1) = 1 奇数

2. 求平均值,比如有两个int类型变量x、y,首先要求x+y的和,再除以2,但是有可能x+y的结果会超过int的最大表示范围,所以位运算就派上用场啦。

(x&y)+((x^y)>>1);

实现原理:我们先了解下面几种情况:

1. 当两个数所有为 1 和为 0 的位都相同时,这两个数的平均值就是 (x & y) 。比如当 x 和 y 都等于 1100 时,x & y 的值也是 1100 ,我们也可以说此时求 x 和 y 的平均数可以用 (x & y) 来求得。

2. 当两个数中的所有对应位有且只有一个为 1 时,那么这两个数的平均值由 (x^y)>>1 表达式求得。比如当 x 为 101100 (十进制 44),y 为 010010 (十进制 18) 时,x ^ y 的值为 111110 ,然后再将 111110 向右移动 1 位后得 11111 (十进制为 31),也就是 (44 + 18)/2 = 31 。

由上面的 情况1 和 情况2 我们知道,将它们两者结合起来便可求得随意两个整数的平均值。

3. 对于一个大于0的整数,判断它是不是2的几次方

((x&(x-1))==0)&&(x!=0);

4. 两者数字交换。比如有两个int类型变量x、y,要求两者数字交换,位运算的实现方法:性能绝对高效

x ^= y;

y ^= x;

x ^= y;

5. 求绝对值

int abs( int x )

{

int y ;

y = x >> 31 ;

return (x^y)-y ; //or: (x+y)^y

}

6. 取模运算,采用位运算实现:

a % (2^n) 等价于 a & (2^n - 1)

7. 乘法运算 采用位运算实现

a * (2^n) 等价于 a << n

8. 除法运算转化成位运算

a / (2^n) 等价于 a>> n

9. 求相反数

(~x+1)

10 a % 2 等价于 a & 1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: