com.github.azbh111.utils.java.bit.BitUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of utils-java Show documentation
Show all versions of utils-java Show documentation
com.github.azbh111:utils-java
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();
}
}