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

c、java移位操作

2017-10-03 15:24 232 查看
昨天记录了一下c和java中的位运算符c和java中的位运算对比—补码运算,发现其实位运算都是针对补码进行运算,但是没有记录移位运算,这里记录一下。

java:主要的结论如下:

1. <<,左移。低位补0。

2. >>,右移。被操作数如果为正数,高位补0;如果为负数,高位补1。

3. java中没有无符号左移,只有无符号右移>>>。不管被操作数为正数还是负数,最高位均补0(视操作位为无符号正数)。

4. 在移位时,byte/short/char类型数,在移位前会被转化为int型(按数值进行转换)。

5. 对于byte/short/char/int型数据,实际移动的次数是 n % 32位。

6. 对于long型,实际移位的次数是 n % 64。

7. 浮点数不能进行移位操作。

验证代码如下:

public class URShift {

public static void main(String[] args) {

//进行移位运算时,位内存中补码的形式
//  0000 0000 0000 0000 0000 0000 1111 1111
//<< 1
//  0000 0000 0000 0000 0000 0001 1111 1110
//左移了1位,低位补0
System.out.println("<<1:" + Integer.toBinaryString(0xff << 1));//1 1111 1110

//  1111 1111 1111 1111 1111 1111 0000 0001
//  <<1
//  1111 1111 1111 1111 1111 1110 0000 0010
//左移了1位,低位补0
System.out.println("<<1:" + Integer.toBinaryString(-0xff << 1));//11111111111111111111111000000010

//编译错误,java中没有无符号左移
//System.out.println("l<<<" + (l <<< 64));

//转化为10进制,结果为-510 != -256 * 2,这里也证明了原来老师教的左移1位相当于乘以2是扯蛋的,不负责任的,至少对于负数是存在错误的
System.out.println(-0xff << 1);//-510

//  0000 0000 0000 0000 0000 0000 1111 1111
//>> 1
//  0000 0000 0000 0000 0000 0000 0111 1111
//右移了1位,高位补0
System.out.println(">>1:" + Integer.toBinaryString(0xff >> 1));//111 1111
//  0000 0000 0000 0000 0000 0000 1111 1111
//>>> 1
//  0000 0000 0000 0000 0000 0000 0111 1111
//  右移了1位,高位补0
System.out.println(">>>1:" + Integer.toBinaryString(0xff >>> 1));//111 1111

//  1111 1111 1111 1111 1111 1111 0000 0001
//  >> 1
//  1111 1111 1111 1111 1111 1111 10000000
//右移了1位,高位补1
System.out.println(">>1:" + Integer.toBinaryString(-0xff >> 1));//11111111111111111111111110000000
//  1111 1111 1111 1111 1111 1111 0000 0001
//  >> 1
//  0111 1111 1111 1111 1111 1111 1000 0000
//右移了1位,高位补0
System.out.println(">>>1:" + Integer.toBinaryString(-0xff >>> 1));//1111111111111111111111110000000
//  0000 0000 0000 0000 0000 0000 1111 1111
//<< 31
//  1000 0000 0000 0000 0000 0000 0000 0000
System.out.println("<<31:" + Integer.toBinaryString(0xff << 31));//10000000000000000000000000000000

//  1111 1111 1111 1111 1111 1111 0000 0001
//  <<31
//  1111 1111 1111 1111 1111 1111 0000 0001
System.out.println("<<31:" + Integer.toBinaryString(-0xff << 31));//11111111111111111111111100000001

//1111 1111 1111 1111 1111 1111 0000 0001
//>>31
//1111 1111 1111 1111 1111 1111 1111 1111
System.out.println(">>31:" + Integer.toBinaryString(-0xff >> 31));//11111111111111111111111111111111

//对于byte/short/char/int型数据,实际移动的次数是 n % 32位
//  1111 1111 1111 1111 1111 1111 0000 0001
//<< 32 相当于移位32 % 32 = 0位
//  1111 1111 1111 1111 1111 1111 0000 0001
System.out.println("<<32:" + Integer.toBinaryString(-0xff << 32));//11111111111111111111111100000001

//  1111 1111 1111 1111 1111 1111 0000 0001
//>>32  相当于移位32 % 32 = 0位
//  1111 1111 1111 1111 1111 1111 0000 0001
System.out.println(">>32:" + Integer.toBinaryString(-0xff >> 32));//11111111111111111111111100000001

char ch = 0xff;
char che = (char)(-0xff);

//在移位时,byte/short/char类型数,在移位前会被转化为int型
//  0000 0000 0000 0000 0000 0000 1111 1111
//<< 31
//  1000 0000 0000 0000 1111 1111 0000 0000
System.out.println("ch<<8:" + Integer.toBinaryString(ch << 8));//1111111100000000

//  1111 1111 1111 1111 1111 1111 0000 0001
//<< 31
//  0000 0000 1111 1111 0000 0001 0000 0000
System.out.println("che << 8:" + Integer.toBinaryString(che << 8));//111111110000000100000000

//对于long型,实际移位的次数是 n % 64
//0x7fffffffffffffff
//<<64 相当于移位64 % 64 = 0 位
//  7fffffffffffffff
long l = Long.MAX_VALUE;
System.out.println("l<<64:" + Long.toHexString(l << 64));

//编译错误,浮点数不能进行移位操作
//System.out.println("0.1 >> 1" + (0.1 >>1));

short s = -1;
System.out.println(Integer.toBinaryString(s));
s >>>= 10;
//运算时先转换为int型,值为1111 1111 1111 1111 1111 1111 1111 1111
//由于赋值时转换为short型数据,前半部分被截断,赋值为1111 1111 1111 1111,真值也为-1
System.out.println(Integer.toBinaryString(s));
}
}


c语言结论如下:

1. <<,左移。低位补0。

2. >>,右移。被操作数如果为正数,高位补0;如果为负数,高位补1。

3. c语言中没有无符号移位

4. 在移位时,byte/short/char类型数,在移位前后都不会被转化为int型。

5. 如果移位溢出,不会处理,会得到随机值。

6. 浮点数不能进行移位操作。

验证代码如下:

#include <stdio.h>

int main(){

//进行移位运算时,位内存中补码的形式
//左移1位,低位补0
printf("%x\n", 0xff << 1);//1fe
printf("%x\n", -0xff << 1);//fffffe02
//右移1位,高位补0
printf("%x\n", 0xff >> 1);//7f
//右移1位,高位补1
printf("%x\n", -0xff >> 1);//ffffff80

printf("%x\n", (-0xff << 31));//80000000
printf("%x\n", (-0xff >> 31));//ffffffff

printf("%x\n", (0xff << 32));//得到的是1个随机值
printf("%x\n", (0xff >> 32));//得到的是1个随机值

long l = 0xff;
printf("%d\n", sizeof(long));
printf("%lx\n", l << 32);//ff 00 00 00 00

short ch = -1;
char che = (char)(-0xff);
printf("%x\n", ch << 1);//ff ff ff fe,可以看出运算结果并没有转换为int型

//编译错误,c语言中没有无符号移位
//printf("%x\n", 0xff <<< 1);
//printf("%d\n", 0xff >>> 1);
//编译错误,小数不能进行移位运算
//printf("%x\n", 0.1 << 1);

return 0;

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