FAQ VCL
Работа с битами

:: Меню ::
:: На главную ::
:: FAQ ::
:: Заметки ::
:: Практика ::
:: Win API ::
:: Проекты ::
:: Скачать ::
:: Секреты ::
:: Ссылки ::

:: Сервис ::
:: Написать ::

:: MVP ::

:: RSS ::

Яндекс.Метрика

Как установить бит (установить значение в 1)?

// Способ первый
function BitOn(const Value: LongInt; const Bit: Byte): LongInt;
begin
   Result := Value or (1 shl Bit);
end;

// Способ второй
function BitOn(const Value: LongInt; const Bit: Byte): LongInt;
begin
   Result := Value or not ((1 shl Bit) xor $FFFFFFFF);
end;


Как сбросить бит (установить значение в 0)?

// Способ первый
function BitOff(const Value: LongInt; const Bit: Byte): LongInt;
begin
   Result := Value and not (1 shl Bit);
end;

// Способ второй
function BitOff(const Value: LongInt; const Bit: Byte): LongInt;
begin
   Result := Value and ((1 shl Bit) xor $FFFFFFFF);
end;


Как переключить состоянии бита (с 1 на 0 и наоборот)?

function BitToggle(const Value: LongInt; const Bit: Byte): LongInt;
begin
   Result := Value xor (1 shl Bit);
end;


Как проверить значение бита?

function IsBitSet(Value: Cardinal; Bit: Byte): Boolean;
begin
   Result := ((Value shr Bit) and 1) = 1;
   // Result := ((Value shr Bit) and 1) <> 0;
end;


Как сделать аналог ассемблерных команд ROL и ROR?

// Циклический сдвиг двойного слова влево
function ROL_DWORD( Val: DWORD; Shift: Byte ): DWORD;
//asm
//   mov cl, dl
//   rol eax, cl
//end;
begin
   Result := ( Val shl Shift ) or ( Val shr ( 32 - Shift ) );
end;

// Циклический сдвиг слова влево
function ROL_WORD( Val: Word; Shift: Byte ): Word;
//asm
//   mov cl, dl
//   rol ax, cl
//end;
begin
   Result := ( Val shl Shift ) or ( Val shr ( 16 - Shift ) );
end;

// Циклический сдвиг байта влево
function ROL_BYTE( Val: Byte; Shift: Byte ): Byte;
//asm
//   mov cl, dl
//   rol al, cl
//end;
begin
   Result := ( Val shl Shift ) or ( Val shr ( 8 - Shift ) );
end;


// Циклический сдвиг двойного слова вправо
function ROR_DWORD( Val: DWORD; Shift: Byte ): DWORD;
//asm
//   mov cl, dl
//   ror eax, cl
//end;
begin
   Result := ( Val shr Shift ) or ( Val shl ( 32 - Shift ) );
end;

// Циклический сдвиг слова вправо
function ROR_WORD( Val: Word; Shift: Byte ): Word;
//asm
//   mov cl, dl
//   ror ax, cl
//end;
begin
   Result := ( Val shr Shift ) or ( Val shl ( 16 - Shift ) );
end;

// Циклический сдвиг байта вправо
function ROR_BYTE( Val: Byte; Shift: Byte ): Byte;
//asm
//   mov cl, dl
//   ror al, cl
//end;
begin
   Result := ( Val shr Shift ) or ( Val shl ( 8 - Shift ) );
end;


Как поменять местами биты?

procedure SwapEndiannessOfBits(var Value: Cardinal);
var
  tmp: Cardinal;
  i: Integer;
begin
   tmp := 0;
   for i := 0 to 8*SizeOf(Value)-1 do
      Inc(tmp, ((Value shr i) and $1) shl (8*SizeOf(Value)-i-1));
   Value := tmp;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  c: Cardinal;
begin
   c := $AAAAAAAA; // => $55555555
   // 10101010101010101010101010101010 => 01010101010101010101010101010101
   SwapEndiannessOfBits(c);
   ShowMessage(IntToHex(c, 8));
end;


Как поменять местами байты?

// Способ первый
procedure SwapEndiannessOfBytes(var Value: Cardinal);
var
  tmp: Cardinal;
  i: Integer;
begin
  tmp := 0;
  for i := 0 to SizeOf(Value)-1 do
    Inc(tmp, ((Value shr (8*i)) and $FF) shl (8*(SizeOf(Value)-i-1)));
  Value := tmp;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  c: Cardinal;
begin
  c := $AABBCCDD; // => $DDCCBBAA
  // 10101010|10111011|11001100|11011101 => 11011101|11001100|10111011|10101010
  SwapEndiannessOfBytes(c);
  ShowMessage(IntToHex(c, 8));
end;

// Способ второй
procedure Swp(var Value: LongWord); assembler;
asm
   mov edx, [Value]
   bswap edx
   mov [Value], edx
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Val: Cardinal;
begin
   Val := $AABBCCDD; // => $DDCCBBAA
   // 10101010|10111011|11001100|11011101 => 11011101|11001100|10111011|10101010
   Swp(Val);
   ShowMessage(IntToHex(Val, 8));
end;

При использовании материала - ссылка на сайт обязательна