You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Delphi中创建用于高效32位操作的TBitSet32记录?

TBitSet32结构的设计与实现方案

一、value字段的类型选择

在Delphi中,Integer是32位有符号整数,Cardinal是32位无符号整数,两者内存占用均为4字节,完全满足你的内存效率需求。如果你的位操作不需要处理符号逻辑,Cardinal会更直观;若需兼容有符号场景,Integer也可以使用——核心是两者都是32位宽度,仅占4字节,远优于布尔数组的32字节开销。

二、完整实现代码

type
  TBitSet32 = record
    value: Cardinal; // 推荐用无符号32位整数,若需有符号可替换为Integer

    // 获取指定位索引对应的位值
    function valueForBit(index: Integer): Boolean;
    // 返回集合中被标记的位的数量
    function count: Integer;
    // 标记指定的位
    procedure markBit(setValue: Boolean; index: Integer);
  end;

{ TBitSet32 }

function TBitSet32.count: Integer;
begin
  // Delphi XE7及以上可用内置高效指令,直接统计置位数量
  Result := PopCnt(value);
  
  // 兼容旧版本Delphi的手动实现(效率略低)
  // var
  //   i: Integer;
  // begin
  //   Result := 0;
  //   for i := 0 to 31 do
  //     if (value and (1 shl i)) <> 0 then
  //       Inc(Result);
  // end;
end;

function TBitSet32.valueForBit(index: Integer): Boolean;
begin
  // 先校验索引合法性(0-31)
  if (index < 0) or (index > 31) then
    raise Exception.Create('Bit index out of range (0-31)');
  
  // 通过位掩码判断指定位是否被设置
  Result := (value and (1 shl index)) <> 0;
end;

procedure TBitSet32.markBit(setValue: Boolean; index: Integer);
begin
  if (index < 0) or (index > 31) then
    raise Exception.Create('Bit index out of range (0-31)');

  if setValue then
    // 置位:用Or操作将指定位置为1
    value := value or (1 shl index)
  else
    // 清位:用And Not操作将指定位置为0
    value := value and not (1 shl index);
end;

三、关键实现说明

  • valueForBit:通过1 shl index生成仅指定位为1的掩码,和value做按位与运算,若结果非零则表示该位已被标记。
  • count:优先使用PopCnt函数,它直接调用CPU的内置指令,统计32位整数中置位的数量,效率极高;旧版本Delphi可以用循环逐个判断每一位的方式实现。
  • markBit:根据传入的setValue参数,选择用Or置位或And Not清位,操作前先校验索引范围避免越界错误。

内容的提问来源于stack exchange,提问作者zeus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 11:42:34