Delphi. Некоторые функции для работы с битами

Получение числа из байтовой строки Signed (если в старшем бите зашифрована информация о знаке, 1 это минус, 0 это плюс) и Unsigned

function GetNumberFromByteStringUnsigned(const s: AnsiString): extended;
var
  i, len: integer;
  mn: extended;
  p: Int64;
begin
  len := Length(s);
  Assert(len > 0);
  if len < 8 then
  begin
    p := 0;
    Move(s[1], p, len);
    Result := p;
  end
  else
  begin
    Result := Ord(s[1]);
    mn := 1;
    for i := 2 to len do
    begin
      mn := mn * 256;
      Result := Result + mn * Ord(s[i]);
    end;
  end;
end;

function GetNumberFromByteString(const s: AnsiString): extended;
var
  i, len: integer;
  mn: extended;
  p: Int64;
begin
  len := Length(s);
  Assert(len > 0);
  if len < 8 then
  begin
    p := 0;
    Move(s[1], p, len);
    if ord(s[len]) shr 7 = 1 then // отрицательная ветка, если старший бит равен 1
      Result := -((int64(1) shl (len * 8)) - p)
    else
      Result := p; // Иначе положительное число
  end
  else
  begin
    Result := Ord(s[1]);
    mn := 1;
    for i := 2 to len do
    begin
      mn := mn * 256;
      Result := Result + mn * Ord(s[i]);
    end;
  end;
end;

Посмотреть биты через строку

function ShowBits(a:byte):string; 
var i: Integer; 
begin 
 for i := 7 downto 0 do 
 // Variant1 
 if (a and (1 shl i))<>0 then Result:=Result+'1' else 
 Result:=Result+'0'; 
 // Variant2 
 //for i:=7 downto 7 do if ((a shr i) and 1)=1 then 
   Result:=Result+'1' 
   else 
   Result:=Result+'0'; 
end;

Заполнение битов из байта

function FillBits(a: Byte): TBits;
var
  i: integer;
begin
    Result := TBits.Create();
    for i := 7 downto 0 do
    if (a and (1 shl i)) <> 0 then
      Result[i] := true
    else
      Result[i] := false;
end;

Превращение битов в integer, для этого aBits нужно заполнить полностью, то есть передать 8*4 = 32 бита

function SomeBitsConvertToInteger(aBits: TBits): integer;
var
  i: Integer;
begin
  if SizeOf(integer) * 8 <> aBits.Size then
    raise Exception.Create('not enough bits');
  Result := 0;
  for i := 0 to aBits.Size - 1 do
      Result := Result or integer((Ord(aBits[i]) shl i));
end;

В данном примере, в первые 5 битов зашифрован масштаб. Если у нас только 5 битов, начиная с младшего, то мы можем сделать так

function GetValue(const int5: integer): Extended;
var
  k: integer;
  mn: extended;
begin
Result := 0;  
 if (int5 and $10) <> 0 then
    k := -((not int5) and $F) - 1
  else
    k := int5;
  mn := 1;
  while k > 0 do
  begin
    Dec(k);
    mn := mn * 10;
  end;
  while k < 0 do
  begin
    Inc(k);
    mn := mn / 10;
  end;
  Result := mn;
end;
This entry was posted in Без рубрики. Bookmark the permalink.