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;

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