All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.azbh111.utils.java.bit.BitUtils Maven / Gradle / Ivy

The newest version!
package com.github.azbh111.utils.java.bit;

/**
 * 二进制操作
 * 某些技巧:
 * 字母转换成大些 'a' & '_' -> 'A' , 'A' & '_' -> 'A'
 * 字母转换成小写 'A' | ' ' -> 'a' , 'a' | ' ' -> 'a'
 * 改变字母大小写 'A' ^ ' ' -> 'a' , 'a' ^ ' ' -> 'A'
 * 判断数字异号 (1 ^ -1) < 0
 * 把二进制表示中的最后一个1变成0 n&(n-1)
 * 如果 n&(n-1) -> 0 那么n是2的幂
 * 可以用来计算汉明权重
 *
 * @author pyz
 * @date 2019/4/13 9:32 PM
 */
public class BitUtils {
    /**
     * 11111111
     */
    public static final byte mask_byte_0xff;
    /**
     * 11111111,11111111
     */
    public static final short mask_short_0xffff;
    /**
     * 11111111,11111111,11111111,11111111
     */
    public static final int mask_int_0xffffffff;
    /**
     * 11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111
     */
    public static final long mask_long_0xffffffffffffffff;
    /**
     * 00000000,00000000,00000000,00000000,11111111,11111111,11111111,11111111
     */
    public static final long mask_long_0x00000000ffffffff;
    /**
     * 11111111,11111111,11111111,11111111,00000000,00000000,00000000,00000000
     */
    public static final long mask_long_0xffffffff00000000;

    static {
        mask_byte_0xff = (byte) 0xff;
        mask_short_0xffff = (short) 0xffff;
        mask_int_0xffffffff = 0xffffffff;
        long v = 0x7fffffff;
        v = (v << 1) | 1;
        mask_long_0x00000000ffffffff = v;
        mask_long_0xffffffff00000000 = mask_long_0x00000000ffffffff << 32;
        mask_long_0xffffffffffffffff = (mask_long_0x00000000ffffffff << 32) | mask_long_0x00000000ffffffff;
    }

    /**
     * 不小于给定值 的 最小的 2的整数次幂
     * 如果超过取值范围, 会返回 Integer.MAX_VALUE
     *
     * @param target capacity 必须为正数
     * @return int
     * @author zhengyongpan
     * @since 2022/2/6 下午2:57
     */
    public static int ceilPowerOf2(int target) {
        if (target <= 0) {
            throw new IllegalArgumentException(String.format("非法输入: %s", target));
        }
        if (isPowerOf2(target)) {
            return target;
        }
        int highestBit = indexOfHighestBit(target);
        if (highestBit == 31) {
            return Integer.MAX_VALUE;
        }
        return (1 << highestBit) << 1;
    }

    /**
     * 计算最高位1的索引, 从0开始
     *
     * @param v v
     * @return int
     * @author zhengyongpan
     * @since 2022/2/6 下午2:42
     */
    public static int indexOfHighestBit(byte v) {
        if (v == 0) {
            return -1;
        }
        if (v < 0) {
            return 7;
        }
        int from = 0;
        int to = 7;
        while (from < to) {
            int mid = from + ((to + 1 - from) >> 1);
            if ((v >>> mid) > 0) {
//                高位有1
                from = mid;
            } else {
//                高位无1
                to = mid - 1;
            }
        }
        return from;
    }


    /**
     * 计算最高位1的索引, 从0开始
     *
     * @param v v
     * @return int
     * @author zhengyongpan
     * @since 2022/2/6 下午2:42
     */
    public static int indexOfHighestBit(short v) {
        if (v == 0) {
            return -1;
        }
        if (v < 0) {
            return 15;
        }
        int from = 0;
        int to = 15;
        while (from < to) {
            int mid = from + ((to + 1 - from) >> 1);
            if ((v >>> mid) > 0) {
//                高位有1
                from = mid;
            } else {
//                高位无1
                to = mid - 1;
            }
        }
        return from;
    }


    /**
     * 计算最高位1的索引, 从0开始
     *
     * @param v v
     * @return int
     * @author zhengyongpan
     * @since 2022/2/6 下午2:42
     */
    public static int indexOfHighestBit(int v) {
        if (v == 0) {
            return -1;
        }
        if (v < 0) {
            return 31;
        }
        int from = 0;
        int to = 31;
        while (from < to) {
            int mid = from + ((to + 1 - from) >> 1);
            if ((v >>> mid) > 0) {
//                高位有1
                from = mid;
            } else {
//                高位无1
                to = mid - 1;
            }
        }
        return from;
    }


    /**
     * 计算最高位1的索引, 从0开始
     *
     * @param v v
     * @return int
     * @author zhengyongpan
     * @since 2022/2/6 下午2:42
     */
    public static int indexOfHighestBit(long v) {
        if (v == 0) {
            return -1;
        }
        if (v < 0) {
            return 63;
        }
        int from = 0;
        int to = 63;
        while (from < to) {
            int mid = from + ((to + 1 - from) >> 1);
            if ((v >>> mid) > 0) {
//                高位有1
                from = mid;
            } else {
//                高位无1
                to = mid - 1;
            }
        }
        return from;
    }


    /**
     * toBytes 的逆向操作
     *
     * @param bytes 0<=length<=4
     * @return
     */
    public static int toInt(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return 0;
        }
        int v = 0;
        int length = Math.min(bytes.length, 4);
        for (int i = 0; i < length; i++) {
            v |= (bytes[i] & 0xff) << (i * 8);
        }
        return v;
    }

    /**
     * toBytes 的逆向操作
     *
     * @param bytes
     * @return
     */
    public static long toLong(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return 0;
        }
        long v = 0;
        int length = Math.min(bytes.length, 8);
        for (int i = 0; i < length; i++) {
            v |= (bytes[i] & 0xffL) << (i * 8);
        }
        return v;
    }

    /**
     * byte[] 低索引 对应 int 低位
     *
     * @param v
     * @return length=4
     */
    public static byte[] toBytes(int v) {
        byte[] bytes = new byte[4];
        bytes[0] = (byte) (v);
        ;
        bytes[1] = (byte) (v >>> 8);
        bytes[2] = (byte) (v >>> 16);
        bytes[3] = (byte) (v >>> 24);
        return bytes;
    }

    /**
     * byte[] 低索引 对应 long 低位
     *
     * @param v
     * @return length=8
     */
    public static byte[] toBytes(long v) {
        byte[] bytes = new byte[8];
        bytes[0] = (byte) (v);
        bytes[1] = (byte) (v = (v >>> 8));
        bytes[2] = (byte) (v = (v >>> 8));
        bytes[3] = (byte) (v = (v >>> 8));
        bytes[4] = (byte) (v = (v >>> 8));
        bytes[5] = (byte) (v = (v >>> 8));
        bytes[6] = (byte) (v = (v >>> 8));
        bytes[7] = (byte) (v = (v >>> 8));
        return bytes;
    }

    /**
     * 高位补0凑够32位
     *
     * @param value
     * @return
     */
    public static int bitsToInt(byte value) {
        return value & mask_byte_0xff;
    }

    /**
     * 高位补0凑够32位
     *
     * @param value
     * @return
     */
    public static int bitsToInt(short value) {
        return value & mask_short_0xffff;
    }

    /**
     * 高位补0凑够64位
     *
     * @param value
     * @return
     */
    public static long bitsToLong(byte value) {
        return value & mask_byte_0xff;
    }

    /**
     * 高位补0凑够64位
     *
     * @param value
     * @return
     */
    public static long bitsToLong(short value) {
        return value & mask_short_0xffff;
    }

    /**
     * 高位补0凑够64位
     *
     * @param value
     * @return
     */
    public static long bitsToLong(int value) {
        return mask_long_0x00000000ffffffff & value;
    }


    /**
     * 反转二进制位
     *
     * @param value
     * @return
     */
    public static byte reverse(byte value) {
        int i = value & 0xff;
        i = (i & 0x5555) << 1 | (i >>> 1) & 0x5555;
        i = (i & 0x3333) << 2 | (i >>> 2) & 0x3333;
        i = (i & 0x0f0f) << 4 | (i >>> 4) & 0x0f0f;
        return (byte) i;
    }

    /**
     * 反转二进制位
     *
     * @param value
     * @return
     */
    public static short reverse(short value) {
        int i = value & 0xffff;
        i = (i & 0x5555) << 1 | (i >>> 1) & 0x5555;
        i = (i & 0x3333) << 2 | (i >>> 2) & 0x3333;
        i = (i & 0x0f0f) << 4 | (i >>> 4) & 0x0f0f;
        i = ((i & 0x00ff) << 8) | (i >>> 8);
        return (short) i;
    }

    /**
     * 反转二进制位
     *
     * @param value
     * @return
     */
    public static int reverse(int value) {
        return Integer.reverse(value);
    }

    /**
     * 反转二进制位
     *
     * @param value
     * @return
     */
    public static long reverse(long value) {
        return Long.reverse(value);
    }

    /**
     * 返回对应的二进制补码
     *
     * @param value
     * @return
     */
    public static String toBinaryString(byte value) {
        return Integer.toBinaryString(value & 0xff);
    }

    /**
     * 返回对应的二进制补码 高位补0
     *
     * @param value
     * @return
     */
    public static String toBinaryFullString(byte value) {
        return ensureLength(toBinaryString(value), 8);
    }

    /**
     * 返回对应的二进制补码
     *
     * @param value
     * @return
     */
    public static String toBinaryString(short value) {
        return Integer.toBinaryString(value & 0xffff);
    }

    /**
     * 返回对应的二进制补码 高位补0
     *
     * @param value
     * @return
     */
    public static String toBinaryFullString(short value) {
        return ensureLength(toBinaryString(value), 16);
    }

    /**
     * 返回对应的二进制补码
     *
     * @param value
     * @return
     */
    public static String toBinaryString(int value) {
        return Integer.toBinaryString(value);
    }


    /**
     * 返回对应的二进制补码 高位补0
     *
     * @param value
     * @return
     */
    public static String toBinaryFullString(int value) {
        return ensureLength(toBinaryString(value), 32);
    }

    /**
     * 返回对应的二进制补码
     *
     * @param value
     * @return
     */
    public static String toBinaryString(long value) {
        return Long.toBinaryString(value);
    }

    /**
     * 返回对应的二进制补码 高位补0
     *
     * @param value
     * @return
     */
    public static String toBinaryFullString(long value) {
        return ensureLength(toBinaryString(value), 64);
    }

    /**
     * 判断异号
     *
     * @param a
     * @param b
     * @return
     */
    public static boolean isDiffSign(int a, int b) {
        return (a ^ b) < 0;
    }

    /**
     * 计算汉明权重(二进制表示中1的个数)
     *
     * @param n
     * @return
     */
    public static int getHammingWeight(int n) {
        int m = 0;
        while (n != 0) {
            n = n & (n - 1);
            m++;
        }
        return m;
    }

    /**
     * 判断是不是2的指数(二进制表示只有一个1)
     *
     * @param n
     * @return
     */
    public static boolean isPowerOf2(int n) {
        if (n <= 0) {
            return false;
        }
        return (n & (n - 1)) == 0;
    }

    private static String ensureLength(String str, int length) {
        if (str.length() == length) {
            return str;
        }
        int append = length - str.length();
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < append; i++) {
            sb.append('0');
        }
        sb.append(str);
        return sb.toString();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy