“嗨,阿米戈!”
“我还想谈谈位掩码和 XOR。”
“您已经知道数字由位组成,您可以对这些位执行各种操作。位掩码表示几个不同的逻辑值(真/假值)作为单个整数。在这种情况下,每个布尔值对应于一个特定的位。这是如何做到的:“
“二(1、2、4、8、16、32,...)的幂的二进制表示只涉及设置一位:”
数字 | 二进制表示 |
---|---|
1个 | 0000 0001 |
2个 | 0000 0010 |
4个 | 0000 0100 |
8个 | 0000 1000 |
16 | 0001 0000 |
19(不是二的幂) | 0001 0011 |
31(不是二的幂) | 0001 1111 |
“因此,任何整数都可以被视为位数组或布尔值数组。”
“以下是如何在一个数字中存储不同的布尔值:”
boolean a = true;
boolean b = false;
boolean c = true;
boolean d = false;
int result = 0;
if (a) result += 1; // 1 == 20 — bit 0
if (b) result += 2; // 2 == 21 — bit 1
if (c) result += 4; // 4 == 22 — bit 2
if (d) result += 8; // 8 == 23 — bit 3
“现在,如果相应的布尔变量为真,则每一位都为 1。”
在我们的例子中,变量 a 和 c 为真,所以结果等于 1+4 == 5
0000 0101
0000 dcba
“我想我知道发生了什么。”
“好吧,既然你明白了,那我们就继续吧。”
“一个int有32位。其中一位用于数字的符号,另外31位可用于存储31个布尔变量的值。”
“一个 long 有 64 位,我们可以在其中存储 63 个布尔变量。”
“是的。”
“一个数字里塞满了几十个变数,真是不少啊。”
“但这适用于什么地方?”
“主要是在你需要存储大量关于对象的信息的情况下。当你存储关于一个对象的大量信息时,总会有几十个布尔变量。“通过这种方法,它们都可以方便地存储在一个数字中”
“重点在‘存’字上。因为实际使用这个号码并不是那么方便。”
“对了,这正是我想问的。我们如何从数字中提取布尔值?”
“一点都不复杂。假设你需要确定第 6 位是否设置为 1(2 的 5 次方是 32)。我们可以这样检查:”
int a = 32; // 25 == 0010 0000
int b = 8; // 23 == 0000 1000
int c = 2; // 21 == 0000 0010
int result = a + b + c; // 32 + 8 + 2 == 42 == 0010 1010
int a = result & 32; // 0010 1010 & 0010 0000 = 0010 0000
int b = result & 8; // 0010 1010 & 0000 1000 = 0000 1000
int c = result & 2; // 0010 1010 & 0000 0010 = 0000 0010
“因此,使用位掩码涉及三个操作:”
1) 将特定位设置为0
2) 将特定位设置为1
3) 检查特定位的值。
“以第 6 位为例。”
“如何将位 6 设置为 1?”
代码 | 描述 |
---|---|
|
如何将第 6 位设置为 1? |
|
如何将第 6 位设置为 0? |
|
你如何获得第 6 位的值? |
“这很不寻常,但并不难。伙计,现在我是一个热门程序员。”
“还有一个关于如何轻松获取特定位设置为 0 或 1 的数字的小提示:01000000 或 10111111。”
为此,我们有 >>和 <<运算符。
“1 是 2 的零次方。换句话说,第 0 位设置为 1 的数字。我们需要第 6 位设置的数字。”
int c = 1 << 6; // 0000 0001 << 6 == 0100 0000 == 64
“太棒了!这对这种情况真的很有帮助。”
“但是,如果我需要一个数字,其中除了一个特定位设置为 0 之外,每个位都设置为 1 怎么办?”
“那也不难:”
int d = ~(1 << 6); // ~0100 0000 == 10111111
“也就是说,一切都很简单:”
代码 | 描述 |
---|---|
|
如何将第 6 位设置为 1? |
|
如何将第 6 位设置为 0? |
|
你如何获得第 6 位的值? |
“看起来并不难。但我不会马上记住它。”
“但是,如果你在别人的代码中遇到像“result &= ~(1 << 6)”这样可怕的表达式,你就会知道这个人只是在使用位掩码。”
“如果你经常遇到它,它就会为你记住自己。”
“记住自己……听起来不错。谢谢你的教训。”
GO TO FULL VERSION