Autor Téma: Hexadecimal to binari  (Přečteno 245 krát)

Vladik

  • Host
Hexadecimal to binari
« kdy: 11-06-2018, 06:44:46 »
Dobrý den.
Když mam Hexadecimal čísla 0xff, 0x00,0x7f, 0xbf.
Bych je potřeboval do binary jako string   11111111, 00000000, 01111111, 10111111.
Děkují.


Offline Delfin

  • Guru
  • *****
  • Příspěvků: 863
  • Karma: 42
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Hexadecimal to binari
« Odpověď #1 kdy: 11-06-2018, 10:05:34 »
Bez kontroly chyb vstupu a ne prilis efektivne (coz je ale u potencialne domaciho ukolu jedno) by se dalo napsat napr.:

Kód: Delphi [Vybrat]
  1. function HexStrToBinStr(const Input: string): string;
  2. const
  3.   BCD: array[0..15] of string =
  4.     ('0000', '0001', '0010', '0011', '0100', '0101', '0110', '0111',
  5.     '1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111');
  6. var
  7.   I: Integer;
  8. begin
  9.   Result := '';
  10.   for I := 3 to Length(Input) do
  11.     case Input[I] of
  12.       '0'..'9': Result := Result + BCD[Ord(Input[I]) - Ord('0')];
  13.       'a'..'f': Result := Result + BCD[Ord(Input[I]) - Ord('a') + 10];
  14.       'A'..'F': Result := Result + BCD[Ord(Input[I]) - Ord('A') + 10];
  15.     end;
  16. end;

Delphi maji funkci HexToBin, ale bylo by treba jeste pridelat konverzi vystupu do retezce. Proto je vyse uvedena ukazka o neco jednodussi.
I'm a soldier, so don't panic!

Vladik

  • Host
Re:Hexadecimal to binari
« Odpověď #2 kdy: 11-06-2018, 11:10:56 »
Není to domácí ukol  ;)

Když mám tedý výstup v LongInt?
Je funkce String(Longint);

Offline našinec

  • Hrdina
  • ****
  • Příspěvků: 368
  • Karma: 5
Re:Hexadecimal to binari
« Odpověď #3 kdy: 11-06-2018, 11:32:05 »
Nevím, zda Ti jde vysloveně o program nebo o převod samotný. Převod umí i kalkulačka ve windows.

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 863
  • Karma: 42
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Hexadecimal to binari
« Odpověď #4 kdy: 11-06-2018, 11:33:46 »
Není to domácí ukol  ;)

Když mám tedý výstup v LongInt?
Je funkce String(Longint);

Nechapu. Pokud ma byt vystupem numericky datovy typ, proc tedy provadet konverzi do binarni soustavy? Nestaci Ti potom primo konverze pomoci StrToInt (prip. TryStrToInt):

Kód: Delphi [Vybrat]
  1. var
  2.   I: Integer;
  3. begin
  4.   I := StrToInt('0x7f');
  5. end;

Nove Delphi rozumi hexadecimalni notaci retezcu s prefixem 0x. Nevim zda tomu tak bylo i ve starsich.
« Poslední změna: 11-06-2018, 12:00:59 od Delfin »
I'm a soldier, so don't panic!

Vladik

  • Host
Re:Hexadecimal to binari
« Odpověď #5 kdy: 11-06-2018, 13:09:25 »
Mam k počitačí připojene arduino na kterým je expander.
Arduino posila do PC stav expanderu.

Když pošle  0x7f a ja si to pak převedu na 01111111, mužu si to rozporcovát a tak zjistím v jakem stavu je každý pin

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 863
  • Karma: 42
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Hexadecimal to binari
« Odpověď #6 kdy: 11-06-2018, 15:12:32 »
Nechapu co chces porcovat. Na numerickou hodnotu kterou mas na vstupu pouzij bitovou masku. Nebo si vymysli numericky datovy typ s pomocnymi funkcemi. Protoze nepredpokladam ze by hodnota stavu portu byla kdy zaporna, pouzil jsem v ukazce datovy typ Cardinal (DWORD):

Kód: Delphi [Vybrat]
  1. function IsBitSet(Value: Cardinal; Index: Byte): Boolean;
  2. begin
  3.   Result := (Value and (1 shl Index)) <> 0;
  4. end;

Pokud Ti ani toto nepomuze, detailne popis co vlastne potrebujes.
I'm a soldier, so don't panic!

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2086
  • Karma: 108
    • Verze Delphi: D2007, XE3, DX10
Re:Hexadecimal to binari
« Odpověď #7 kdy: 11-06-2018, 16:08:10 »
Excellent
Rated 1 time
Pokud Ti ani toto nepomuze, detailne popis co vlastne potrebujes.
Ucebnici uplnych zakladu programovani  :)

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 863
  • Karma: 42
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Hexadecimal to binari
« Odpověď #8 kdy: 11-06-2018, 16:16:59 »
Pokud Ti ani toto nepomuze, detailne popis co vlastne potrebujes.
Ucebnici uplnych zakladu programovani  :)

V dnesni dobe se na to uz nehraje. Pokud nema jazyk zapouzdreni vseho ve vesmiru, lidi ho prestanou pouzivat :) Pritom by EMBT stacilo jen kopirovat co umi napr. C# (ten ma pro tento pripad BitArray; Delphi ma tridu TBits, ale te chybi rozumne konstruktory).
« Poslední změna: 11-06-2018, 16:32:09 od Delfin »
I'm a soldier, so don't panic!

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 863
  • Karma: 42
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Hexadecimal to binari
« Odpověď #9 kdy: 11-06-2018, 18:57:40 »
A to se navic v dobe dnesnich Delphi da napsat spousta uzasnych pomocniku (tedy, skoda ze muze byt jen jeden aktivni). Ale i tak, metody co se drive balily do objektu se daji pribalit i zakladnim typum. Coz je super. Jen jich EMBT moc nenabizi a vetsina programatoru o nich nema poneti.
« Poslední změna: 11-06-2018, 19:01:38 od Delfin »
I'm a soldier, so don't panic!

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 863
  • Karma: 42
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Hexadecimal to binari
« Odpověď #10 kdy: 11-06-2018, 22:41:30 »
Napr. nasledujici ukazka mi zabrala zhruba 10 minut bez vetsiho rozmyslu (nema ani podporu volby endianess). Samozrejme neni ani otestovana patricnym unit testem a je dost mozne ze obsahuje chyby (jde jen o predstavu, nejde o hotove ani optimalni reseni!). Jde jen o vlastni typ dynamickeho, generickeho pole Boolean s pomocnikem:

Kód: Delphi [Vybrat]
  1. resourcestring
  2.   SBitArraySizeDiffer = 'Array size is different. Size: %d. Requested: %d.';
  3.   SBitIndexOutOfBounds = 'Bit index out of bounds. Index: %d. Range: [%d..%d]';
  4.  
  5. type
  6.   TBitArray = TArray<Boolean>;
  7.  
  8.   TBitArrayHelper = record helper for TBitArray
  9.   strict private
  10.     const
  11.       BitsPerByte = 8;
  12.     procedure CheckSize(Size: Integer); inline;
  13.     procedure CheckIndex(Index: Integer); inline;
  14.     function GetBit(Index: Integer): Boolean; inline;
  15.     procedure SetBit(Index: Integer; Value: Boolean); inline;
  16.     function GetAsUInt8: UInt8; inline;
  17.     procedure SetAsUInt8(Value: UInt8); inline;
  18.     function GetAsUInt16: UInt16; inline;
  19.     procedure SetAsUInt16(Value: UInt16); inline;
  20.     function GetAsUInt32: UInt32; inline;
  21.     procedure SetAsUInt32(Value: UInt32); inline;
  22.   public
  23.     class function New(Value: UInt8): TBitArray; overload; static; inline;
  24.     class function New(Value: UInt16): TBitArray; overload; static; inline;
  25.     class function New(Value: UInt32): TBitArray; overload; static; inline;
  26.     property Bit[Index: Integer]: Boolean read GetBit write SetBit;
  27.     property AsUInt8: UInt8 read GetAsUInt8 write SetAsUInt8;
  28.     property AsUInt16: UInt16 read GetAsUInt16 write SetAsUInt16;
  29.     property AsUInt32: UInt32 read GetAsUInt32 write SetAsUInt32;
  30.   end;
  31.  
  32. { TBitArrayHelper }
  33.  
  34. class function TBitArrayHelper.New(Value: UInt8): TBitArray;
  35. var
  36.   I: Integer;
  37. begin
  38.   SetLength(Result, SizeOf(Value) * BitsPerByte);
  39.   for I := 0 to High(Result) do
  40.     Result[I] := (Value and (1 shl I)) <> 0;
  41. end;
  42.  
  43. class function TBitArrayHelper.New(Value: UInt16): TBitArray;
  44. var
  45.   I: Integer;
  46. begin
  47.   SetLength(Result, SizeOf(Value) * BitsPerByte);
  48.   for I := 0 to High(Result) do
  49.     Result[I] := (Value and (1 shl I)) <> 0;
  50. end;
  51.  
  52. class function TBitArrayHelper.New(Value: UInt32): TBitArray;
  53. var
  54.   I: Integer;
  55. begin
  56.   SetLength(Result, SizeOf(Value) * BitsPerByte);
  57.   for I := 0 to High(Result) do
  58.     Result[I] := (Value and (1 shl I)) <> 0;
  59. end;
  60.  
  61. procedure TBitArrayHelper.CheckSize(Size: Integer);
  62. begin
  63.   if Length(Self) <> Size then
  64.     raise ERangeError.CreateResFmt(@SBitArraySizeDiffer, [Length(Self), Size]);
  65. end;
  66.  
  67. procedure TBitArrayHelper.CheckIndex(Index: Integer);
  68. begin
  69.   if (Index < Low(Self)) or (Index > High(Self)) then
  70.     raise ERangeError.CreateResFmt(@SBitIndexOutOfBounds, [Index, Low(Self), High(Self)]);
  71. end;
  72.  
  73. function TBitArrayHelper.GetBit(Index: Integer): Boolean;
  74. begin
  75.   CheckIndex(Index);
  76.   Result := Self[Index];
  77. end;
  78.  
  79. procedure TBitArrayHelper.SetBit(Index: Integer; Value: Boolean);
  80. begin
  81.   CheckIndex(Index);
  82.   Self[Index] := Value;
  83. end;
  84.  
  85. function TBitArrayHelper.GetAsUInt8: UInt8;
  86. var
  87.   I: Integer;
  88. begin
  89.   CheckSize(SizeOf(Result) * BitsPerByte);
  90.   Result := 0;
  91.   for I := Low(Self) to High(Self) do
  92.     if Self[I] then
  93.       Result := Result + (1 shl I);
  94. end;
  95.  
  96. procedure TBitArrayHelper.SetAsUInt8(Value: UInt8);
  97. begin
  98.   CheckSize(SizeOf(Value) * BitsPerByte);
  99.   Self := TBitArray.New(Value);
  100. end;
  101.  
  102. function TBitArrayHelper.GetAsUInt16: UInt16;
  103. var
  104.   I: Integer;
  105. begin
  106.   CheckSize(SizeOf(Result) * BitsPerByte);
  107.   Result := 0;
  108.   for I := Low(Self) to High(Self) do
  109.     if Self[I] then
  110.       Result := Result + (1 shl I);
  111. end;
  112.  
  113. procedure TBitArrayHelper.SetAsUInt16(Value: UInt16);
  114. begin
  115.   CheckSize(SizeOf(Value) * BitsPerByte);
  116.   Self := TBitArray.New(Value);
  117. end;
  118.  
  119. function TBitArrayHelper.GetAsUInt32: UInt32;
  120. var
  121.   I: Integer;
  122. begin
  123.   CheckSize(SizeOf(Result) * BitsPerByte);
  124.   Result := 0;
  125.   for I := Low(Self) to High(Self) do
  126.     if Self[I] then
  127.       Result := Result + (1 shl I);
  128. end;
  129.  
  130. procedure TBitArrayHelper.SetAsUInt32(Value: UInt32);
  131. begin
  132.   CheckSize(SizeOf(Value) * BitsPerByte);
  133.   Self := TBitArray.New(Value);
  134. end;

Pouziti pak muze byt bud pres pseudokonstruktor New, nebo primo pri praci s takovym polem. Moznosti jak si pomoci s bitovou manipulaci jsou mraky. Urcite vsak ne archaickou tridou TBits. Ta je ostudou EMBT...

Na pripadny dotaz proc jsem nepouzil skutecny record constructor ani nazev Create pro metodu vracejici referenci noveho recordu predem odpovim - nerad micham tridy s recordy, a je tim o neco zretelnejsi ze volani TBitArray.New(...) nevraci objekt nutny k nasledne destrukci.

Zakladni myslenkou bylo vytvorit pole Boolean ktere je mozne inicializovat pomoci pseudokonstruktoru New a s kterym bude mozne manipulovat jen v ramci mezi rozsahu poctu bitu (elementu) pole. Tim netvrdim ze je implementace spravne (vic nez 10 minut se mi nad tim travit ted nechce).
« Poslední změna: 11-06-2018, 23:10:21 od Delfin »
I'm a soldier, so don't panic!

 

S rychlou odpovědí můžete používat BB kódy a emotikony jako v běžném okně pro odpověď, ale daleko rychleji.

Jméno: E-mail:
Ověření:
Křestní jméno zpěváka Gotta: