源码看JAVA【三十三】Bits

版权声明: https://blog.csdn.net/jiangxuexuanshuang/article/details/88211114
Bits是位操作的工具类,其中用到了一系列经典的位移操作。

1、字节反转,可参考具体的实现。

   
    static short swap(short x) {
        return Short.reverseBytes(x);
    }

    static char swap(char x) {
        return Character.reverseBytes(x);
    }

    static int swap(int x) {
        return Integer.reverseBytes(x);
    }

    static long swap(long x) {
        return Long.reverseBytes(x);
    }

// short反转:保留第二个字节然后右移八位(变成第一个字节)(逻辑或)第一个字节左移八位变成(第二个字节)达到两个字节交换的目的
    public static short reverseBytes(short i) {
        return (short) (((i & 0xFF00) >> 8) | (i << 8));
    }

// int反转:四个字节,前两个字节右移三个字节和一个字节。后两个字节分别左移1个字节和三个字节,达到交换的目的。
    public static int reverseBytes(int i) {
        return ((i >>> 24)           ) |
               ((i >>   8) &   0xFF00) |
               ((i <<   8) & 0xFF0000) |
               ((i << 24));
    }

// long反转:
// 原排序为 8 7 6 5 4 3 2 1
// i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;
// 保存结果如下,数据并未丢失:
// 7 0 5 0 3 0 1 0
// 0 8 0 6 0 4 0 2
// 即 7 8 5 6 3 4 1 2
// (i << 48) 得到 1 2 0 0 0 0 
// ((i & 0xffff0000L) << 16) 得到 0 0 3 4 0 0 0 0
// ((i >>> 16) & 0xffff0000L) 得到 0 0 0 0 5 6 0 0
// (i >>> 48) 得到 0 0 0 0 0 0 7 8
// 反转后得到:1 2 3 4 5 6 7 8
// 结论:位移运算博大精深
    public static long reverseBytes(long i) {
        i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;
        return (i << 48) | ((i & 0xffff0000L) << 16) |
            ((i >>> 16) & 0xffff0000L) | (i >>> 48);
    }

2、char/short/int/long的put/get操作,基本类似,此处以char为例。不同字节的算法又与swap一致。

3、makeChar:将两个字节拼接成一个char类型,Short也占位两个字节,所以与char操作一致。

实现方式:b1左移八位成为高位字节,b0为低位字节,两个值逻辑或之后成为两个字节,转化为char

    static private char makeChar(byte b1, byte b0) {
        return (char)((b1 << 8) | (b0 & 0xff));
    }

4、getCharL/putCharL 操作ByteBuffer

这两个函数互相对应。get方法,ByteBuffer低位高位与char的低位高位对应,put方法,获取char的两个字节,也是低位与高位对应。

    static char getCharL(ByteBuffer bb, int bi) {
        return makeChar(bb._get(bi + 1),
                        bb._get(bi    ));
    }

    static void putCharL(ByteBuffer bb, int bi, char x) {
        bb._put(bi    , char0(x));
        bb._put(bi + 1, char1(x));
    }

5、getCharL/putCharL 操作寄存器便宜量

这两个函数互相对应。get方法,获取本地地址的低位高位与char的低位高位对应,put方法,获取char的两个字节,也是直接设置到本地地址的低位与高位。

    static char getCharL(long a) {
        return makeChar(_get(a + 1),
                        _get(a    ));
    }

    static void putCharL(long a, char x) {
        _put(a    , char0(x));
        _put(a + 1, char1(x));
    }

6、getCharB/putCharB低位与高位错位设置,其它逻辑与getCharL/putCharL 类似

    static char getCharB(ByteBuffer bb, int bi) {
        return makeChar(bb._get(bi    ),
                        bb._get(bi + 1));
    }

    static char getCharB(long a) {
        return makeChar(_get(a    ),
                        _get(a + 1));
    }

    static void putCharB(ByteBuffer bb, int bi, char x) {
        bb._put(bi    , char1(x));
        bb._put(bi + 1, char0(x));
    }

    static void putCharB(long a, char x) {
        _put(a    , char1(x));
        _put(a + 1, char0(x));
    }

7、char与short是两个字节,所以错位只需第一个字节与第二个字节交换。int与long分别为4字节与8字节,相应的反转逻辑与swap中的操作一致

猜你喜欢

转载自blog.csdn.net/jiangxuexuanshuang/article/details/88211114
今日推荐