Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.08.11;
Скачать: CL | DM;

Вниз

Как извлечь значение конкретного бита в типе byte?   Найти похожие ветки 

 
NetKnight ©   (2003-07-29 13:16) [0]

Субж! Считываю в буфер информацию, а обработать её надо побитно.. Как извлечь значения?

И ещё в добавок: как наиболее оптимально считать из файла данные и представить их в бинарном виде?
В данный момент юзаю BlockRead, а потом конвертирую в массив из byte.


 
VaS ©   (2003-07-29 13:35) [1]

IsFiveBit := (b shr 6) and 1 <> 0;


 
Verg ©   (2003-07-29 13:36) [2]

if (<переменная типа byte> and (1 shl <номер конкретного бита>))<>0 then <этот бит =1> else <этот бит=0>

Биты нумеруются 0..7


> В данный момент юзаю BlockRead, а потом конвертирую в массив
> из byte.


Интересно как выглядит "конвертация".


 
Verg ©   (2003-07-29 13:38) [3]


> VaS ©


Тож нормально. Если уж совсем на Паскале, то
odd(b shr n), b- байт(и не только) n -номер бита


 
HolACost   (2003-07-29 14:40) [4]

Лишний вызов - это уже серьёзнее!


 
han_malign ©   (2003-07-29 15:05) [5]

> IsFiveBit := (b shr 6) and 1 <> 0;
- а не проще, тогда уж IsFiveBit := (b and $20) <> 0
хотя (1 shl < константа - номер конкретного бита>) - это константа рассчитанная на этапе компиляции ((1 shl 5)<==>$20)...

а битовый поток действительно:

for j:=0 to DataSize-1 do begin
b:=Data[j];
for i:=0 to 7 do begin
if((b and 1)<>0)then DoBit1
else DoBit0;
b:=b shr 1;
end;
end;

хотя, для удобства чтения битового потока(глазами), в шестнадцатиричном побайтовом виде, обычно, делают первый бит старшим (CA BE ==> 11001010 10111110, вместо 0101001 10111110 1 ==>56 7D - с первым удобнее читать поток,байты переворачивать не надо(в голове)) и разбирать поток надо:

for j:=0 to DataSize-1 do begin
b:=Datap[j];
for i:=0 to 7 do begin
if((b and $80)<>0)then DoBit1
else DoBit0;
b:=b sh l 1;
end;
end;



 
default ©   (2003-07-29 16:08) [6]

можно юзать вот этот класс


EBitsError_ = class(Exception);
TRange = (r_8, r_16, r_32);

TBits_ = class
private
FNumber: Cardinal;
FRange: Byte;
function GetBit(Index: Byte): Boolean;
procedure SetBit(Index: Byte; Value: Boolean);
procedure SetRange(Value: TRange);
function GetRange: TRange;
procedure SetNumber(Value: Cardinal);
procedure Error;
public
constructor Create(Number: Cardinal; RangeValue: TRange = r_32);
property Number: Cardinal read FNumber write SetNumber;
property Bits[Index: Byte]: Boolean read GetBit write SetBit; default;
property Range: TRange read GetRange write SetRange;
end;

constructor TBits_.Create(Number: Cardinal; RangeValue: TRange = r_32);
begin

FNumber := Number;
Range := RangeValue

end;

function TBits_.GetRange: TRange;
begin

case FRange of
$F8: Result := r_8;
$F0: Result := r_16;
$E0: Result := r_32;
end;

end;

procedure TBits_.SetRange(Value: TRange);
begin

case Value of
r_8 : begin
FRange := $F8;
FNumber := FNumber and $000000FF;
end;
r_16 : begin
FRange := $F0;
FNumber := FNumber and $0000FFFF;
end;
r_32 : FRange := $E0;
end;

end;

procedure TBits_.Error;
begin

raise EBitsError_.Create("The borders are broken")

end;

function TBits_.GetBit(Index: Byte): Boolean;
asm

MOV DH, Self.FRange
TEST DL, DH
JNZ TBits_.Error
MOV EAX, Self.FNumber
MOV CL, DL
SHR EAX, CL
AND EAX, 1

end;

procedure TBits_.SetBit(Index: Byte; Value: Boolean);
asm

MOV DH, Self.FRange
TEST DL, DH
JNZ TBits_.Error
MOVZX EDX, DL
TEST CL, 1
JZ @@ResetBit
BTS Self.FNumber, EDX
RET
@@ResetBit:
BTR Self.FNumber, EDX

end;

procedure TBits_.SetNumber(Value: Cardinal);
begin

if Value <> FNumber then begin
FNumber := Value;
Range := Range;
end;

end;


procedure TForm1.Button3Click(Sender: TObject);
var
b: TBits_;
begin

b := TBits_.Create($FFFFFFEF, r_16);
// b.Number = $0000FFEF
b.Range := r_8;
// b.Number = $000000EF ( $EF = 11101111b )
if not b[4] then begin b[4] := True; b[0] := False; end;
// b.Number = $000000FE ( $FE = 11111110b = 254 )
Caption := IntToStr(b.Number);
Sleep(1000);
try // исключение - обращение к 8 биту при Range = r_8
b[8] := True;
except
on EBitsError_ do Caption := "Обработка исключения класса TBits_";
end;

end;



Страницы: 1 вся ветка

Текущий архив: 2003.08.11;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.027 c
6-33249
drnet
2003-06-06 03:58
2003.08.11
TWebBrowser не отрабатывает OnBeforeNavigate под XP


14-33261
Jeer
2003-07-23 15:17
2003.08.11
Занимательная экономика


3-33046
victor_ch
2003-07-15 09:29
2003.08.11
Вызов хранимой процедуры в запросе


14-33298
VEG
2003-07-17 13:40
2003.08.11
Говорили, что W98 официально похоронят в конце июня...


3-33054
Аня
2003-07-18 08:36
2003.08.11
SELECT не работает