Zdravím.
Když mám Hexadecimal třeba 0x7f
Dovedu si to převest do binari řetězce 01111111
A pak pomocí copy nebo MidStr zjistít stav jednotlivých bitu.
Jde to jednodušejí už s 0x7f třeba pomocí masky?
#2 gna
Jsem to zkoušel pomocí te masky AND a nějak to nechapu
0xaa je 10101010
Tedy jsou zaple bity 0x02,0x08.0x20,0x80.
Jak zjistím pomocí té masky, který bit je zaplý a který vyply?
0xaa je řetězec, takže si ho převedeme na integer a mame decimal 170
#34 MilanL
cyklus 0 až sizeof(číslo)*8 - 1
podmínka číslo AND 1 - podmínka splněna, když číslo.bit0 = 1
... obsluha podmínky then ... else
číslo := číslo shr 1; - posune bity o 1 doprava
konec cyklu
Pozor ten posun ti to číslo vymaže, pokud chceš zachovat musíš použít pomocnou proměnnou, nebo si udělat funkci na rotaci dle odkazu, http://www.delphigroups.info/2/50/21333.html
SHR - shift, ti krajní bit zahodí
ROR - rotace, ti krajní bit přehodí na druhou stranu - tzn po dokončení cyklu dle bitové velikosti proměnné je v proměnné stejná hodnota jako na začátku.
Pokud ti nejde jen o počet 0 a jedniček, ale třeba o binární zobrazení, je třeba vzít v úvahu směr - zprava doleva
A jaký že je tvůj způsob?
Testování bitu pokud mám hex-string bych já osobně udělal asi takhle:
Function TestBit(const Str: String; BitIndex: Integer): Boolean;
var
Num: Integer;
begin
If (BitIndex >= 0) and (BitIndex <= (SizeOf(Integer) * 8)) then
begin
Num := StrToInt(Str);
Result := (Num shr BitIndex) and 1 <> 0
end
else raise Exception.CreateFmt('TestBit: Bit index (%d) out of allowed range.',[BitIndex]);
end;
#5 Borisek
no taky můžeš v cyklu nastavovat masku
taky to jde maskováním tzn číslo zůstane stejné a pomocí generované masky si otestuješ bity
úpravy v mém kodu
maska := 1;
cyklus
if číslo and maska
po podmínce maska := maska SHL 1; lze použít i maska * 2
můj příklad funguje na včechny celočíselné typy a je univerzální, je jen na tobě co dáš do podmínky když je bit 1 a co když je 0
#3 Borisek
Když se ptáš na masku, tak předpokládám, že víš k čemu maskování je -- k "zakrývání a odkrývání" bitů. And vynuluje bity, které jsou v masce nulové a nechá beze změny bity, které jsou v masce jedničkové.
10101010
and 00001111
= 00001010
10101010
and 11110000
= 10100000
$aa and $01 = $00
$aa and $02 = $02
$aa and $04 = $00
$aa and $08 = $08
#3 Borisek
-> "Jak zjistím pomocí té masky, který bit je zaplý a který vyply?"
Takhle:
if (číslo and 0x02)=0 then ...bit 0x02 je vyplý... else ...bit 0x02 je zaplý...;
Závorku píšu jenom pro přehlednost, není nutná - v pascalu má and větší prioritu než =. Můžeš kontrolovat i víc bitů najednou (maska třeba 0x7F), v takovém případě ti ta nula vyjde, když jsou všechny kontrolované bity vyplé. Nebo můžeš otočit logiku:
if (číslo and 0x02)=0x02 then ...bit 0x02 je zaplý... else ...bit 0x02 je vyplý...;
Vhodné pro případ, kdy kontroluješ několik bitů najednou a hledáš nějakou přesnou kombinaci (ne jenom všechno nula / aspoň něco jedna, ale tady jedna, tady nula atd.). Pro jednotlivé bity zbytečná práce, protože to číslo bitu musíš psát dvakrát.
P.S.: pascal standardně píše hexa čísla jako $něco, notace 0xněco je céčková. Ale nevím, možná v některých překladačích funguje.
cislo and 0x01 = xxxx xxxx and 0000 0001 = 0000 000x - bud je to 0 nebo ruzne od nuly
cislo and 0x02 = xxxx xxxx and 0000 0010 = 0000 00x0
cislo and 0x04 = xxxx xxxx and 0000 0100 = 0000 0x00
Cyklem se shiftovanim nebo x = 1; x =x * 2; to muzes rotovat.
a s pomocí XOR můžeš zas zjistit jestli je tam právě ta daná kombinace bitů - tam kde jsou na stejných místech stejné stavy bude ve výslednu 0, tak kde se stavy liší bude 1
A5 1010 0101 . . . . . . 1010 0101
A5 1010 0101 . . 5A .. 0101 1010
xor. 0000 0000 . . . . . . 11111 1111
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku