关于本文
本文是通过利用生成式 AI 的自动化工作流创建的。我们确认了 Microsoft 官方的 PowerShell 和 VBA 位运算规范,并通过纯小整数解释了将 1、2、4 标志进行 OR 组合以及用 AND 进行判断的原因。验证状态:📘 已确认 Microsoft 官方规范,未在 PowerShell/VBA 实机上验证
信息确认基准日:2026年10月5日
查看 Windows API 或旧的 VBA 代码时,经常会看到选项值像 1、2、4、8 这样排列,并且它们被组合后存入一个整数中。
这是将各个功能分配到不同比特位上的位标志。
用二进制看 1、2、4
Read = 1 = 0001 Write = 2 = 0010 Delete = 4 = 0100
各个数值中 1 的位置没有重叠。
当要启用 Read 和 Write 时,在 PowerShell 中可以使用 -bor。
$Read = 1 $Write = 2 $flags = $Read -bor $Write $flags
结果是 3。
在二进制中,它是
0001 0010 ---- 0011
。
OR 表示“如果任一位为 1,则结果为 1”
flowchart LR
A["Read 0001"] --> C["OR"]
B["Write 0010"] --> C
C --> D["0011 = 3"]
PowerShell 的 -bor 会比较整数的各个位,如果其中一位或两位都为 1,则结果为 1。
在 VBA 中,针对数值的 Or 作为按位 OR 运算工作。
Const FlagRead As Long = 1 Const FlagWrite As Long = 2 Dim flags As Long flags = FlagRead Or FlagWrite
使用 AND 检查“是否包含该功能”
检查是否包含 Read。
PowerShell:
($flags -band $Read) -ne 0
VBA:
(flags And FlagRead) <> 0
0011 AND 0001 因为是 0001 ,所以不为 0。也就是说,Read 位已被置 1。
Delete 是
0011 AND 0100 = 0000
,因此不包含在内。
不能因为“加起来也是 3”就认为它们是相同的
这一点最为重要。
1 + 2 = 3 1 OR 2 = 3
单看它,似乎标志用加法就足够了。
但是,重复相同的位时结果则不同。
1 + 1 = 2 1 OR 1 = 1
加法会进位。而 OR 是“将该位置为 1”的操作,如果本来就是 1,则保持 1 不变。
因此,由于是互不重叠的 2 的幂,有时结果会巧合地相同因此加法和OR并非相同的运算。
尝试只修改一处
在 Read + Write 的状态中再加上 Delete。
PowerShell:
$Delete = 4 $flags = $Read -bor $Write -bor $Delete
期望的值是 7,如果用二进制表示则是 0111。
接下来仅检查 Write。
($flags -band $Write) -ne 0
通过让每个二进制位拥有各自的功能,可以用一个整数来表示多个开/关状态。
Any 和 All 是不同的
在判断多个必需的标志时,要区分是“只需满足其中之一即可”还是“全部必需”。
例如,必需的掩码为 Read OR Write = 3,当前的 flags 为 Read OR Delete = 5 的情况。
$required = 3 $flags = 5 $common = $flags -band $required $hasAny = $common -ne 0 $hasAll = $common -eq $required
在这种情况下,因为 Read 是共同的,所以是 hasAny=True,由于没有 Write,所以是 hasAll=False。
频繁出现在 Windows API 常量中的原因
在 Win32 API 等中,为了向一个参数传递多个选项,经常采用组合标志值的经典设计。
00000001 = Option A 00000010 = Option B 00000100 = Option C 00001000 = Option D
只要各自处于不同的二进制位,只需查看一个整数就能保存多个状态。
不过,实际的API中不仅有“单一标志”,还有将多个bit组合在一起的复合常量。不要凭值随意做加法,应当确认该API的官方规范。
chmod的数字也有类似的看法
Linux权限中使用的 4、2、1 也可以通过
read = 4
write = 2
execute = 1
这样的bit组合来理解。
7 可以表示为 4+2+1 ,但本质上是3个权限bit全部置位(开启)的状态。
如果在实际工作中使用,还需注意数据类型
处理标志时,应确认:
是32位还是64位
是有符号(signed)还是无符号(unsigned)
如何处理未知bit
是复合掩码还是单一标志
教材中的 1/2/4 切勿直接套用到实际系统的权限值中。
Daily-Code-Samples
这里提供了可复用的版本,分别对比了 PowerShell 版、VBA 版以及 Any/All 的实现。
