Delphi 将位集作为 TBits 转换为 Integer 或 unsigned int

Delphi Convert Set Of Bits as TBits to Integer or unsigned int

我有来自 nor 或 xor 门的值,表示为 TBits,我想将它转换为通用变量,如整数或无符号整数我当前的工作 ide Tokyo 10.2

var
  ABits: TBits;
  AComulative: UInt32;

const
  PosBitFromSensor1 = 0;
  PosBitFromSensor2 = 1;

begin
  ABits := TBits.Create;
  try
    ABits.Size := 32;
    {GetValFromSensor return Boolean type}
    ABits.Bits[PostBitFromSensor1] := GetValFromSensor(PosBitFromSensor1); 
    ABits.Bits[PostBitFromSensor2] := GetValFromSensor(PosBitFromSensor2);
    AComulative := SomeBitsConvertToInteger(ABits); {some function like this}
  finally
    ABits.Free;
  end;
end;

或任何简单的解决方案。

可能是这样的:

type

  {$IF CompilerVersion > 32} // tokyo
    {$MESSAGE Fatal 'Check if TBits still has the exact same fields and adjust the IFDEF'}
  {$ENDIF}
  TPrivateAccessBits = class
  public
    FSize: Integer;
    FBits: Pointer;
  end;

Move(@TPrivateAccessBits(ABits).FBits, AComulative, sizeOf(AComulative));

此解决方案由@Victoria 和@LURD 提供,可能对其他有相同解决问题的人有用。对不起我的英语。

type
  TBitsHelper = class helper for TBits
  public
    function ToUInt32: UInt32;
  end;

{ TBitsHelper }

function TBitsHelper.ToUInt32: UInt32;
type
  PUInt32 = ^UInt32;
begin
  if Size > SizeOf(Result) * 8 then
    raise EOverflow.Create('Size overflow!');
  with Self do
    Result := PUInt32(FBits)^;
end;

它不会很快,但您可以进行常规位操作,设置布尔数组中对应于 "true" 的每个位。例如:

function SomeBitsConvertToInteger(ABits: TBits): UInt32;
var
  i: Integer;
begin
  if ABits.Size <> SizeOf(Result) * 8 then
    raise EBitsError.Create('Invalid bits size');
  Result := 0;
  for i := 0 to Pred(SizeOf(Result) * 8) do
    Result := Result or UInt32((Ord(ABits[i]) shl i));
end;