有人能解释一下这是如何工作的吗?非常感谢:)
define("FLAG_A", 1);
define("FLAG_B", 2);
define("FLAG_C", 4);
function test_flags($flags=false) {
if ($flags & FLAG_A) echo "A";
if ($flags & FLAG_B) echo "B";
if ($flags & FLAG_C) echo "C";
}
test_flags(FLAG_A|FLAG_B);
这是使用所谓的逐位数学来完成的。具体来说,他们使用&
(按位和)操作来检查是否设置了值。为了便于讨论,我们将使用4位数字,使其简洁明了。
4位二进制的数字7如下:
0111
每个数字都有一个值,每次都会加倍,所有数字加在一起,形成7的总数。分解后,它是这样工作的:
0 1 1 1
^ ^ ^ ^
| | | |
8 4 2 1
所以,本质上,它是:
0 * 8 + 1 * 4 + 1 * 2 + 1 * 1 = 7
现在,使用逐位数学,特别是逐位数学和,我们可以说我们只关心某些列中的位——基本上,每列中的位数必须是1,否则将被设置为零。因此,用比特数学检查"7"中的"4":
0111 (7)
& 0100 (4)
______
0100 (4)
由于该值为非零,因此它为真,并且我们可以确定值4在值7内。现在考虑数字11:
1 0 1 1
^ ^ ^ ^
| | | |
8 4 2 1
1 * 8 + 0 * 4 + 1 * 2 + 1 * 1 = 11
尝试在中查找4
1011 (11)
& 0100 (4)
______
0000 (0)
由于它的值为0,因此它为false,并且我们可以认为数字(4)不在数字11内。
同样,我们可以得出结论,数字4、2和1,而不是8,都在7中。在11中,我们有8、2和1。通过将数字视为一系列比特,而不是奇异值,我们可以在一个整数中存储许多标志。
一定要多读一些关于比特数学的书,如果使用得当,它会非常有用,只是不要试图把它塞进所有的东西里。
这是基于位运算符的。想想
define("FLAG_A", 0001); // in binary form
define("FLAG_B", 0010);
define("FLAG_C", 0100);
因此,例如,$flags & FLAG_A
是变量$flags
和常数FLAG_A
之间的按位AND。