如何将多个小整数保存在一个整数中进行位移?
How do I save multiple small integers in one integer via bitshifting?
我在一个 int[][][]
数组中工作,我需要从一个静态函数 return 该数组的一个字段的地址。
鉴于数组的维度将保持较小 (int[32][32][32]
),我想 return 一个包含所有三个值的数字,而不是使用包含三个数字的数组。
我已经有了一个可行的解决方案,我将我的号码打包成一个字符串,然后通过 Integer.parseInt(String)
在接收方法中将其解包。
不幸的是,这在运行时方面效果不佳,所以我想到了位移位。
我为我糟糕的英语道歉,希望这个简单的问题值得您花时间:)
如果您的数字在 0...255 范围内,此示例会将三个数字编码为一个 int,然后再次对其进行解码...
public class BitDemo {
public static void main(String[] args) {
int encoded = encode(20, 255, 10);
int[] decoded = decode(encoded);
System.out.println(Arrays.toString(decoded));
}
private static int[] decode(int encoded) {
return new int[] {
encoded & 0xFF,
(encoded >> 8) & 0xFF,
(encoded >> 16) & 0xFF
};
}
private static int encode(int b1, int b2, int b3) {
return (b1 & 0xFF) | ((b2 & 0xFF) << 8) | ((b3 & 0xFF) << 16);
}
}
(b1 & 0xFF)
- 获取 b1
的前 8 位
((b2 & 0xFF) << 8)
- 获取 b2 的前 8 位并将它们左移 8 位
((b3 & 0xFF) << 16)
- 获取 b3 的前 8 位并将它们左移 16 位
这三个数字进行或运算。
如果你有负数或大于 255 的数字,你会得到不同的结果。
给定 N
、M
和 O
并假设 N * M * O
没有溢出,您可以像这样打包和解包索引:
int packed = o * (N * M) + m * N + n;
int o = packed / (N * M);
int m = (packed % (N * M)) / N;
int n = packed % N; // is equal to (packed % (N * M)) % N
如果要使用位移位,请确保选择 N, M, O
作为 2 的幂。假设 N = 2^NS
、M = 2^MS
和 O = 2^OS
打包和解包看起来像这样:
int packed = (o << (NS + MS)) | (m << NS) | n;
int o = (packed >> (NS + MS)) & ((1 << OS) - 1);
int m = (packed >> NS) & ((1 << MS) - 1);
int n = packed & ((1 << NS) - 1);
以上所有假设 n=0..N-1
、m=0..M-1
和 o=0..O-1
。
我在一个 int[][][]
数组中工作,我需要从一个静态函数 return 该数组的一个字段的地址。
鉴于数组的维度将保持较小 (int[32][32][32]
),我想 return 一个包含所有三个值的数字,而不是使用包含三个数字的数组。
我已经有了一个可行的解决方案,我将我的号码打包成一个字符串,然后通过 Integer.parseInt(String)
在接收方法中将其解包。
不幸的是,这在运行时方面效果不佳,所以我想到了位移位。
我为我糟糕的英语道歉,希望这个简单的问题值得您花时间:)
如果您的数字在 0...255 范围内,此示例会将三个数字编码为一个 int,然后再次对其进行解码...
public class BitDemo {
public static void main(String[] args) {
int encoded = encode(20, 255, 10);
int[] decoded = decode(encoded);
System.out.println(Arrays.toString(decoded));
}
private static int[] decode(int encoded) {
return new int[] {
encoded & 0xFF,
(encoded >> 8) & 0xFF,
(encoded >> 16) & 0xFF
};
}
private static int encode(int b1, int b2, int b3) {
return (b1 & 0xFF) | ((b2 & 0xFF) << 8) | ((b3 & 0xFF) << 16);
}
}
(b1 & 0xFF)
- 获取 b1
((b2 & 0xFF) << 8)
- 获取 b2 的前 8 位并将它们左移 8 位
((b3 & 0xFF) << 16)
- 获取 b3 的前 8 位并将它们左移 16 位
这三个数字进行或运算。
如果你有负数或大于 255 的数字,你会得到不同的结果。
给定 N
、M
和 O
并假设 N * M * O
没有溢出,您可以像这样打包和解包索引:
int packed = o * (N * M) + m * N + n;
int o = packed / (N * M);
int m = (packed % (N * M)) / N;
int n = packed % N; // is equal to (packed % (N * M)) % N
如果要使用位移位,请确保选择 N, M, O
作为 2 的幂。假设 N = 2^NS
、M = 2^MS
和 O = 2^OS
打包和解包看起来像这样:
int packed = (o << (NS + MS)) | (m << NS) | n;
int o = (packed >> (NS + MS)) & ((1 << OS) - 1);
int m = (packed >> NS) & ((1 << MS) - 1);
int n = packed & ((1 << NS) - 1);
以上所有假设 n=0..N-1
、m=0..M-1
和 o=0..O-1
。