c、java移位操作

昨天记录了一下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;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值