Delphi Can
Byte & Set Of - Baskı Önizleme

+- Delphi Can (https://www.delphican.com)
+-- Forum: Delphi (https://www.delphican.com/forumdisplay.php?fid=3)
+--- Forum: Access violation (https://www.delphican.com/forumdisplay.php?fid=136)
+--- Konu Başlığı: Byte & Set Of (/showthread.php?tid=1502)

Sayfalar: 1 2


Byte & Set Of - Tuğrul HELVACI - 08-11-2017

Amaç: Elimizdeki 1 Byte'lık veri türünün bitlerini değiştirmek, okumak.


Kullanıcılacak Yöntem: Dilin set of yapısal tipi ve set'lerle işlem yapabilen yerleşik metodlar.

İstenilenler:
  1. Herhangi byte türündeki bir değişkenin 1,3,5,7 nci bitlerini set edip, ekranda değeri gösteriniz.
  2. Herhangi byte türündeki bir değişkenin 0,2,4,6 ncı bitlerini set edip, ekranda değeri gösteriniz.
  3. Herhangi byte türündeki bir değişkenin 1,2,3,4 ncı bitlerini set edip, ekranda değeri gösteriniz.
  4. Herhangi byte türündeki bir değişkenin hangi bitlerinin set edildiğini bulunuz.
Her bir madde 5 puan değerindedir.


Byte & Set Of - SimaWB - 08-11-2017

type
 TBit = (Bit0,  Bit1,  Bit2,  Bit3,  Bit4, Bit5,  Bit6,  Bit7);
 TBitSet = set of Bit0..Bit7;

function SetBit(const Value: Byte; const Index: TBit): Byte;
begin
 Result := Value or (1 shl Ord(Index));
end;

function ResetBit(const Value: Byte; const Index: TBit): Byte;
begin
 Result := Value and (not (1 shl Ord(Index)));
end;

function SetBits(const Value: Byte; bits: TBitSet): Byte;
var
 i: TBit;
begin
 Result := Value;
 for i in bits do
   Result := SetBit(Result, i);
end;

function ResetBits(const Value: Byte; bits: TBitSet): Byte;
var
 i: TBit;
begin
 Result := Value;
 for i in bits do
   Result := ResetBit(Result, i);
end;


Artık hangi bitleri set/reset etmek istiyorsak SetBits/ResetBits fonksiyonunun ikinci parametresine set olarak bildirebiliriz. 
Örneğin 1,3,5,7. bitleri set etmek için:
SetBits(ByteDegisken, [Bit1,  Bit3, Bit5, Bit7]);



Byte & Set Of - Tuğrul HELVACI - 08-11-2017

Teşekkür ederim, lâkin beklediğim yanıt bu değil. Amacımız ilgili bitleri setlemek ya da değerlerini elde etmek ama bunu yaparken logical operatörleri kullanmamak. Sizin örneğinizden söyleyecek olursam eğer, istenen TBitSet veri türünü kullanmanız.


Cvp: Byte & Set Of - Tuğrul HELVACI - 08-11-2017

(08-11-2017, Saat: 15:29)uparlayan Adlı Kullanıcıdan Alıntı:
program BitManupilasyonu;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  ArrByte = Array of Byte;

function GetBit(const aBayt: Byte; const aIndex: Byte): Boolean; overload;
begin
  Result := (aBayt and (1 shl (aIndex-1))) <> 0;
end;

function GetBit(const aByte: Byte): String; overload;
var
  I: Integer;
begin
  for I := 1 to 8
  do  if (GetBit(aByte, I) = True) then Result := Result + '1' else Result := Result + '0';
end;

function SetBit(aBayt: Byte; aIndex: Byte): Byte; overload;         // Tek bir bitin değerini değiştirir... 1 > 0 ~ 0 > 1 gibi...
begin
  Result := aBayt or ( Byte(1) SHL (aIndex-1) );
end;

function SetBit(aBayt: Byte; aIndex: ArrByte): Byte; overload;
var
  I: Integer;
begin
  Result := aBayt;
  for I := Low(aIndex) to High(aIndex) do Result := SetBit(Result, aIndex[I]);
end;

var
  BiBayt: Byte;
begin
  BiBayt := 0; // Tüm bitler 0, yani 0x00000000
  BiBayt := SetBit(BiBayt, [1,3,5,7]); Writeln('1,3,5,7 = ' + BiBayt.ToString + ' > 0x' + GetBit(BiBayt)); BiBayt := 0;
  BiBayt := SetBit(BiBayt, [0,2,4,6]); Writeln('0,2,4,6 = ' + BiBayt.ToString + ' > 0x' + GetBit(BiBayt)); BiBayt := 0;
  BiBayt := SetBit(BiBayt, [1,2,3,4]); Writeln('1,2,3,4 = ' + BiBayt.ToString + ' > 0x' + GetBit(BiBayt)); BiBayt := 0;

  readln;
end.

Teşekkür ederim, lâkin arzuladığımız çözüm bu değil. Arzulanan, bitleri okuma ve yazma işlemleri sırasında and, or, xor, shl, shr vb operatörlerin kullanılmamasıdır Uğur bey.

Çok daha basit bir yolu mevcut Wink


Byte & Set Of - SimaWB - 08-11-2017

(08-11-2017, Saat: 15:22)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Sizin örneğinizden söyleyecek olursam eğer, istenen TBitSet veri türünü kullanmanız.

TBitSet türünü kullanıyorum ama Smile



Sanırım altın kural bu: "bit bazlı operatörler kullanılmayacak"
Deneyelim bakalım Wink


Byte & Set Of - Bahadir.Alkac - 08-11-2017

type
  TBit = (Bit0,  Bit1,  Bit2,  Bit3,  Bit4, Bit5,  Bit6,  Bit7);
  TBitSet = set of Bit0..Bit7;
end;

procedure Test;
var
  I: TBit;
  BitSet: TBitSet;
  Test: Byte;
begin
 // Madde 1
  BitSet := [Bit1, Bit3, Bit5, Bit7];
  Test := PByte(@BitSet)^;
  ShowMessage(IntToStr(Test));

  // Madde 2
  BitSet := [Bit0, Bit2, Bit4, Bit6];
  Test := PByte(@BitSet)^;
  ShowMessage(IntToStr(Test));

  // Madde 3
  BitSet := [Bit0, Bit1, Bit3, Bit4];
  Test := PByte(@BitSet)^;
  ShowMessage(IntToStr(Test));

  // Madde 4
  for I := Bit0 to Bit7 do
  begin
    if I in TBitSet(Test)  then
      ShowMessage(IntToStr(Integer(I)) + ' set edilmiş');
  end;
end;



Cvp: Byte & Set Of - Tuğrul HELVACI - 08-11-2017

(08-11-2017, Saat: 16:05)Bahadir.Alkac Adlı Kullanıcıdan Alıntı:
type
  TBit = (Bit0,  Bit1,  Bit2,  Bit3,  Bit4, Bit5,  Bit6,  Bit7);
  TBitSet = set of Bit0..Bit7;
end;

procedure Test;
var
  I: TBit;
  BitSet: TBitSet;
  Test: Byte;
begin
 // Madde 1
  BitSet := [Bit1, Bit3, Bit5, Bit7];
  Test := PByte(@BitSet)^;
  ShowMessage(IntToStr(Test));

  // Madde 2
  BitSet := [Bit0, Bit2, Bit4, Bit6];
  Test := PByte(@BitSet)^;
  ShowMessage(IntToStr(Test));

  // Madde 3
  BitSet := [Bit0, Bit1, Bit3, Bit4];
  Test := PByte(@BitSet)^;
  ShowMessage(IntToStr(Test));

  // Madde 4
  for I := Bit0 to Bit7 do
  begin
    if I in TBitSet(Test)  then
      ShowMessage(IntToStr(Integer(I)) + ' set edilmiş');
  end;
end;

Teşekkür ederim. Ellerinize sağlık. Puanınızı verdim, ama pointerlara bulaşmadan daha kolay bir yolu daha mevcut Wink


Byte & Set Of - SimaWB - 08-11-2017

(08-11-2017, Saat: 16:05)Bahadir.Alkac Adlı Kullanıcıdan Alıntı:
type
  TBit = (Bit0,  Bit1,  Bit2,  Bit3,  Bit4, Bit5,  Bit6,  Bit7);
  TBitSet = set of Bit0..Bit7;
end;

procedure Test;
var
  I: TBit;
  BitSet: TBitSet;
  Test: Byte;
begin
 // Madde 1
  BitSet := [Bit1, Bit3, Bit5, Bit7];
  Test := PByte(@BitSet)^;
  ShowMessage(IntToStr(Test));

  // Madde 2
  BitSet := [Bit0, Bit2, Bit4, Bit6];
  Test := PByte(@BitSet)^;
  ShowMessage(IntToStr(Test));

  // Madde 3
  BitSet := [Bit0, Bit1, Bit3, Bit4];
  Test := PByte(@BitSet)^;
  ShowMessage(IntToStr(Test));

  // Madde 4
  for I := Bit0 to Bit7 do
  begin
    if I in TBitSet(Test)  then
      ShowMessage(IntToStr(Integer(I)) + ' set edilmiş');
  end;
end;

Burada bir yanlışlık yok mu?
Ben mi soruyu yanlış yorumladım bilemiyorum ama elimizdeki değişkenin sadece istenen bitlerini değiştirmemiz gerekmiyor mu? Yani diğer bitlerinin sabit kalması gerekiyor  Idea


Byte & Set Of - uparlayan - 08-11-2017

İpucu verebiliyor muyuz?


Cvp: Byte & Set Of - Tuğrul HELVACI - 08-11-2017

Benim çözümüm de aşağıdaki gibi:

type
  TByteSet = set of 0..SizeOf(Byte) * 8 - 1;

procedure TForm1.Button1Click(Sender: TObject);
var
 AByteSet  : TByteSet;
 AValue    : Byte;
 iCounter  : Integer;
begin
 AValue := 8;
 ShowMessage(AValue.ToString);

 AByteSet := TByteSet(AValue);
 Include(AByteSet, 0);

 AValue := Byte(AByteSet);
 ShowMessage(AValue.ToString());

 TByteSet(AValue) := [0,1];
 ShowMessage(AValue.ToString());

 AByteSet := [];
 for iCounter := 0 to 7 do
   if (iCounter mod 2) <> 0 then
     Include(AByteSet, iCounter);

 AValue := Byte(AByteSet);
 ShowMessage(AValue.ToString());
end;