lok*_*oki 1 delphi pascal freepascal
我正在开发一个项目,需要非常有效地操作一组 32 位。内存效率至关重要,因此使用布尔数组(占用 32 个字节)不是一个选择(如果我可以有其他选择,速度是最重要的)。
这是我为 TBitSet32 设想的结构:
TBitSet32 = record
value: ?integer?; // I'm not sure about the datatype here. Should it be Integer or another type?
// Gets the value associated with a particular bit index.
function valueForBit(index: integer): boolean;
// Returns the number of marked bits in the set.
function count: integer;
// Marks the specified bit.
procedure markBit(value: boolean; index: integer);
end;
Run Code Online (Sandbox Code Playgroud)
对于值字段,我认为我需要 32 位整数类型。Integer 这里的选择正确吗?如何实现 valueForBit、count 和 markBit 方法?
对于此记录的任何见解或示例实现,我将不胜感激。
如果您正好需要 32 位,那么(U)Int32
比Integer
. 剩下的只是使用and
、or
和shl
/shr
运算符进行位操作,例如:
type
TBitSet32 = record
FSet: UInt32;
// Gets the value associated with a particular bit index.
function valueForBit(index: integer): boolean;
// Returns the number of marked bits in the set.
function count: integer;
// Marks the specified bit.
procedure markBit(value: boolean; index: integer);
end;
function TBitSet32.valueForBit(index: integer): boolean;
begin
Result := (FSet and (1 shl index)) <> 0;
end;
function TBitSet32.count: integer;
var
I: Integer;
tmp: UInt32;
begin
Result := 0;
tmp := FSet;
for I := 0 to 31 do begin
Inc(Result, tmp and 1);
tmp := tmp shr 1;
end;
end;
procedure markBit(value: boolean; index: integer);
begin
if value then
FSet := FSet or (1 shl index)
else
FSet := FSet and not (1 shl index);
end;
Run Code Online (Sandbox Code Playgroud)
也就是说,考虑使用 aSet
代替,并让编译器为您处理位操作,因为 aSet
是使用位集实现的,例如:
type
TBitSet32 = record
FSet: set of 0..31;
// Gets the value associated with a particular bit index.
function valueForBit(index: integer): boolean;
// Returns the number of marked bits in the set.
function count: integer;
// Marks the specified bit.
procedure markBit(value: boolean; index: integer);
end;
function TBitSet32.valueForBit(index: integer): boolean;
begin
Result := index in FSet;
end;
function TBitSet32.count: integer;
var
I: Integer;
begin
Result := 0;
for I := 0 to 31 do
Inc(Result, Ord(I in FSet));
end;
procedure markBit(value: boolean; index: integer);
begin
if value then
Include(FSet, index)
else
Exclude(FSet, index);
end;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
215 次 |
最近记录: |