Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Datentypen von String zu Byte und wieder zurück (https://www.delphipraxis.net/192538-datentypen-von-string-zu-byte-und-wieder-zurueck.html)

Graw 27. Apr 2017 13:05

Datentypen von String zu Byte und wieder zurück
 
Hi,

ich hoffe ihr könnt mir helfen.
Also folgendes, ich bekomme über eine Schnittstelle zwei Strings. Die sehen zum Beispiel so aus:

1. Datensatz: 003F800
2. Datensatz: 001FC00

Die einzelnen Zeichen in dem String muss ich nun so umformen, das ich die hex Zeichen im String zu Binary umforme:

1. Datensatz: 0000|0000|0011|1111|1000|0000|0000
2. Datensatz: 0000|0000|0001|1111|1100|0000|0000

Diese beiden Datensätze muss ich dann zu einem zusammenfügen.
Dazu nehme ich das erste Zeichen von Datensatz 2 dann das erste von Datensatz 1 dann das zweite von Datensatz 2 usw.

1 u. 2 zusammen: 0000|0000|0000|0000|0000|0111|1111|1111|1110|0000| 0000|0000|0000|0000

Und dann wieder umwandeln in einen String mit den Hex Werten

1 u. 2 zusammen: 0|0|0|0|0|7|F|F|E|0|0|0|0|0


Ich hoffe ich habe das verständlich erklärt.
Im Voaraus schonmal vielen Dank.

sko1 27. Apr 2017 13:15

AW: Datentypen von String zu Byte und wieder zurück
 
Wozu die zwischenzeitliche Umkonvertierung in Bits und wieder zurück?

Du nimmst doch eigentlich aus den beiden Strings (das sind keine Datensätze!) jeweils die Zeichen!

Dazu stimmt Dein Beispiel nicht!

Mein Beispiel:

1) 12345
2) ABCDE

Ergebnis soll sein

A1B2C3D4E5 richtig?

Nur mal zusammengetippt:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
a,b,r : string;
i : integer;
begin
a := '12345';
b := 'ABCDE';

r := '';
for i := 1 to 5 do
  r := r + b[i] + a[i];

ShowMessage(r);
end;

Ciao
Stefan

Graw 27. Apr 2017 13:23

AW: Datentypen von String zu Byte und wieder zurück
 
Hi,

entschuldige meine falsche Ausdrucksweise :oops:

Die "Sortierung" die du gemacht hast ist für mich nicht ausreichend.

Wenn ich mein Beispiel nehme wird aus:

003F800 + 001FC00 = 000007FFE00000
und nicht:

003F800 + 001FC00 = 000013FFC80000

sko1 27. Apr 2017 13:28

AW: Datentypen von String zu Byte und wieder zurück
 
Zitat:

1. Datensatz: 0000|0000|0011|1111|1000|0000|0000
2. Datensatz: 0000|0000|0001|1111|1100|0000|0000

Diese beiden Datensätze muss ich dann zu einem zusammenfügen.
Dazu nehme ich das erste Zeichen von Datensatz 2 dann das erste von Datensatz 1 dann das zweite von Datensatz 2 usw.

0|0|0|0|0|7|F|F|E|0|0|0|0|0

Bitte beschreibe den Algorithmus genauer!
Deine beiden Ausgangswerte haben je 2 Nullen vorn, Dein Ergebnis hat vorn 5 Nullen
Dann kommt eine 1 und eine 3, warum wird da im Ergebnis 7?

Ich verstehe immer noch nicht was Du da eigentlich machen willst!

Ciao
Stefan

Uwe Raabe 27. Apr 2017 13:29

AW: Datentypen von String zu Byte und wieder zurück
 
Ich verstehe das so, daß du die beiden Hex-Strings bitweise verschachtelst. Folgende Funktion sollte das leisten:

Delphi-Quellcode:
function Convert(const A, B: string): string;

  function Merge(CA, CB: Char): string;
  type
    TByteSet = set of 0..3;
  var
    BS: TByteSet;
    b1: Byte;
    b2: Byte;
    I: Integer;
  begin
    b1 := StrToInt('$' + CA);
    b2 := StrToInt('$' + CB);
    BS := [];
    for I := 0 to 3 do begin
      if I in TByteSet(b1) then begin
        Include(BS, 2*I);
      end;
      if I in TByteSet(b2) then begin
        Include(BS, 2*I + 1);
      end;
    end;
    Result := IntToHex(Byte(BS), 2);
  end;

var
  I: Integer;
begin
  Assert(Length(A) = Length(B), 'Strings müssen gleich lang sein!');
  Result := '';
  for I := 1 to Length(A) do begin
    Result := Result + Merge(A[I], B[I]);
  end;
end;

Graw 27. Apr 2017 15:08

AW: Datentypen von String zu Byte und wieder zurück
 
Hallo Uwe,

deine Funktion ist genau das was ich gebraucht habe.
Vielen Dank!!!

Wenn ich zwei feste Strings in die Funktion eintrage kommt genau das Ergebniss welches ich mir erhofft habe.

Die Strings die von der Schnittstelle kommen will er leider noch nicht verarbeiten...
Da hab ich irgendwo noch nen Fehler...

Aber den soll ich wohl noch finden.

Nochmal vielen Dank!!

himitsu 27. Apr 2017 17:42

AW: Datentypen von String zu Byte und wieder zurück
 
BS hat offiziell nur 4 Bit, aber irgendwer tut da 8 Bits rein .... so ganz Richtig kann das nicht sein. :zwinker:


Deine Beschreibung war in #1 nicht so gut.
Für mich klang das auch so, als wenn du jeweils "ein Hex-Zeichen" mischen willst und nicht die einzelnen Bits.

Olli73 27. Apr 2017 19:55

AW: Datentypen von String zu Byte und wieder zurück
 
Zitat:

Zitat von himitsu (Beitrag 1369333)
BS hat offiziell nur 4 Bit, aber irgendwer tut da 8 Bits rein .... so ganz Richtig kann das nicht sein. :zwinker:

Kam mir auch komisch vor. Aber habe es gerade mal im Debugger gecheckt: Der tut da anstandslos mehr rein als deklariert ist.

Also wenn ich doppelt so viele Bit trinke, wie ich eigentlich vertrage, dann kommt es bei mir zu einem Überlauf... ;)

Michael II 27. Apr 2017 21:01

AW: Datentypen von String zu Byte und wieder zurück
 
Ja, immer wieder spannend was man so alles in eine einfache Menge packen kann :-D.

Ich nehm mal an, dass das viele Delphianer nicht wissen und UR uns allen damit wieder einmal zeigen wollte, was Delphi so alles kann ;-).

Schnell ist das aber nicht.

Wenn viele Daten anfallen / Tempo eine Rolle spielt, dann kann man es auch so machen:

Delphi-Quellcode:
var merger : array[0..15,0..15] of string;
    hti : array[ '0'..'F' ] of integer;

function ConvertA(const A, B: string): string;
var i : integer;
begin
  Assert(Length(A) = Length(B), 'Strings müssen gleich lang sein!');
  Result := '';
  for i := 1 to length(A) do Result := Result + merger[hti[A[i]],hti[B[i]]];
end;
Das ist auf meiner Kiste über 16 Mal schneller und da die beiden Algos O(n) sind, ist das wohl auch auf langsameren und schnelleren Kisten so.

Uwe Raabe 27. Apr 2017 22:02

AW: Datentypen von String zu Byte und wieder zurück
 
Zitat:

Zitat von himitsu (Beitrag 1369333)
BS hat offiziell nur 4 Bit, aber irgendwer tut da 8 Bits rein .... so ganz Richtig kann das nicht sein. :zwinker:

Gut erkannt!
Delphi-Quellcode:
TByteSet
muss natürlich so deklariert sein:

Delphi-Quellcode:
  type
    TByteSet = set of 0..7;
Übrigens: Das funktioniert deshalb, weil Delphi immer ganze Bytes für Sets reserviert.

Zitat:

Zitat von Michael II (Beitrag 1369342)
Schnell ist das aber nicht.

Klar, daß man das mit einer Lookup-Tabelle deutlich schneller laufen lassen kann (deren Aufbau hast du ja auch weg optimiert - alternativ als
Delphi-Quellcode:
const
deklarieren). Es ging mir hier aber im Wesentlichen darum, den beschriebenen Algorithmus möglichst exakt nachzubilden.

himitsu 27. Apr 2017 22:35

AW: Datentypen von String zu Byte und wieder zurück
 
Ja, Natürlich kann man nur auf ganze Bytes zugreifen und Delphi rundet immer auf.
Ein Boolean kennt auch 1x False und 255x True :stupid:

Aber blöd wird es, wenn man die Bereichsprüfung mal aktiviert und dann der Typ zu klein deklariert ist.

Uwe Raabe 28. Apr 2017 08:13

AW: Datentypen von String zu Byte und wieder zurück
 
Liste der Anhänge anzeigen (Anzahl: 1)
Das ist sogar noch witziger:
Delphi-Quellcode:
type
  TSet = set of 0..3;

procedure Main;
var
  s: TSet;
  I: 0..3;
begin
  s := [1,3];
  for I in s do
  begin         // <== BreakPoint 1
    Writeln(I); // <== BreakPoint 2
  end;
end;            // <== BreakPoint 3
BreakPoint 1 wird 8x durchlaufen! BreakPoint 2 erwartungsgemäß nur 2x.

Bei den Durchläufen vor dem ersten Writeln hat I nicht mal einen definierten Wert.

Graw 28. Apr 2017 09:43

AW: Datentypen von String zu Byte und wieder zurück
 
Leider bekomm ich es doch nicht ans laufen...

Wenn ich der Funktion feste Werte übergebe funktioniert sie wunderbar.
Code:
PBuf := Convert('00003FFFC000','00003FFFC000');
Wenn ich aber meine Buffer der Funktion übergebe kommt nichts aus ihr raus.
Code:
BEGIN

          PBuf1 := Copy(PBuf10,13,Length(PBuf10)-3);
          PBuf2 := Copy(PBuf20,13,Length(PBuf20)-3);


          if (length(PBuf1) = length(PBuf2)) then
          begin
           PBuf := Convert(PBuf1,PBuf2);
           PBufSend := PBuf;        
          end;
         
END;
Könnt ihr mir sagen was ich da falsch mache?

Olli73 28. Apr 2017 09:59

AW: Datentypen von String zu Byte und wieder zurück
 
Wie sind denn die PBuf.. deklariert und was sagt der Debugger?

Graw 28. Apr 2017 10:06

AW: Datentypen von String zu Byte und wieder zurück
 
Ist alles als String deklariert

Olli73 28. Apr 2017 10:10

AW: Datentypen von String zu Byte und wieder zurück
 
Dann setze mal einen Haltepunkt und schau dir an was in den Strings, die du übergibst, drin steht.

Uwe Raabe 28. Apr 2017 10:20

AW: Datentypen von String zu Byte und wieder zurück
 
Zitat:

Zitat von Graw (Beitrag 1369355)
Delphi-Quellcode:
PBuf1 := Copy(PBuf10,13,Length(PBuf10)-3);

Was soll damit erreicht werden? Vorausgesetzt, PBuf10 ist als string deklariert, dann versuchst du hier 9 Zeichen mehr zu kopieren als vorhanden sind. Delphi fängt das natürlich ab, aber der Code riecht nach einem Fehler.

:glaskugel: Eventuell versuchst du ja auch nur die ersten 12 und die letzen 2 oder 3 Zeichen abzuschneiden? Dann ist das aber der falsche Befehl.

Graw 28. Apr 2017 10:36

AW: Datentypen von String zu Byte und wieder zurück
 
:? Ja das Stimmt.. Ich will von dem String die ersten 12 Zeichen wegschneiden und am Ende die letzten drei.


Ist es so besser?

Code:
BEGIN

          Delete(PBuf10,0,12);
          Delete(PBuf20,0,12);
          Delete(PBuf10,length(PBuf10)-3,3);
          Delete(PBuf10,length(PBuf20)-3,3);


          if (length(PBuf10) = length(PBuf20)) then
          begin
           PBuf := Convert(PBuf10,PBuf20);
           PBufSend := PBuf;      
          end;
         
END;

Es sind alle Buffer mit string deklariert. Die Strings sind alle 60 Zeichen lang.

Uwe Raabe 28. Apr 2017 11:04

AW: Datentypen von String zu Byte und wieder zurück
 
Zitat:

Zitat von Graw (Beitrag 1369368)
Ist es so besser?

Welche Delphi-Version und welche Zielplattform?

Graw 28. Apr 2017 11:07

AW: Datentypen von String zu Byte und wieder zurück
 
Delphi 2010 Windows 7

Michael II 28. Apr 2017 11:12

AW: Datentypen von String zu Byte und wieder zurück
 
Hallo Graw,

du weisst doch wie man in der IDE den Debugger nutzt?

Du kannst damit bequem Zeile für Zeile durch dein Programm steppen und dabei beobachten wie sich die Werte deiner Variablen ändern und findest den/die Fehler in deinem Code so sicher sehr rasch.

In deinem Fall überwache die Ausdrücke PBuf, PBuf10, PBuf20 und setze einen Breakpoint bei deiner ersten Zeile und lass es laufen :-).

Uwe Raabe 28. Apr 2017 11:32

AW: Datentypen von String zu Byte und wieder zurück
 
Zitat:

Zitat von Graw (Beitrag 1369368)
Ist es so besser?

In (deinem) Delphi sind Strings 1-basiert. Daher besser so:
Delphi-Quellcode:
Delete(PBuf10, 1, 12);
Delete(PBuf20, 1, 12);
Delete(PBuf10, length(PBuf10) - 2, 3);
Delete(PBuf20, length(PBuf20) - 2, 3); // In deinem Code veränderst du übrigens PBuf10!
Du kannst auch Copy verwenden:
Delphi-Quellcode:
PBuf10 := Copy(PBuf10, 13, Length(PBuf10) - 15);
PBuf20 := Copy(PBuf20, 13, Length(PBuf20) - 15);
Oder das Ganze gleich in eine eigene Funktion kapseln:
Delphi-Quellcode:
function ClipString(const Value: string; Head, Tail: Integer): string;
begin
  result := Copy(Value, Head + 1, Length(Value) - (Head + Tail));
end;

PBuf10 := ClipString(PBuf10, 12, 3);
PBuf20 := ClipString(PBuf20, 12, 3);

Olli73 28. Apr 2017 11:40

AW: Datentypen von String zu Byte und wieder zurück
 
Delphi-Quellcode:
PBuf1 := Copy(PBuf10,13,Length(PBuf10)-15);
Edit: Habe übersehen, dass das schon oben steht.

Luckie 1. Mai 2017 01:49

AW: Datentypen von String zu Byte und wieder zurück
 
Warum nimmst du nicht einfach zwei Variablen, in denen du das erst mal zwischenspeicherst. Das macht den Code auch übersichtlicher.

Graw 2. Mai 2017 09:23

AW: Datentypen von String zu Byte und wieder zurück
 
Hat nun doch alles geklappt. Hatte meine Strings nicht richtig geschnitten.

Vielen Dank.

Blup 3. Mai 2017 09:17

AW: Datentypen von String zu Byte und wieder zurück
 
Ein anderer Weg, mit reinem Assembler geht das natürlich noch kompakter:
Delphi-Quellcode:
function Rol(const AValue: LongWord; const ACount: Byte): LongWord; register;
asm
  mov cl, dl
  rol eax, cl
end;

function IntConvert(A, B: LongWord): Int64;
var
  i: integer;
begin
  Result := 0;
  for i := 0 to 31 do
  begin
    Result := Result shl 1;
    B := Rol(B, 1);
    Result := Result or (B and $00000001);

    Result := Result shl 1;
    A := Rol(A, 1);
    Result := Result or (A and $00000001);
  end;
end;

function Convert(const A, B: string): string;
var
  aa, bb: LongWord;
begin
  aa := StrToInt('$' + A);
  bb := StrToInt('$' + B);
  Result := IntToHex(IntConvert(aa, bb), 16);
end;

himitsu 3. Mai 2017 09:39

AW: Datentypen von String zu Byte und wieder zurück
 
Delphi-Quellcode:
  for i := 0 to 31 do
  begin
    Result := Result shl 1;
    B := B shl 1;
    Result := Result or (B shr 31);

    Result := Result shl 1;
    A := A shl 1;
    Result := Result or (A shr 31);
  end;
:?:

Blup 3. Mai 2017 12:05

AW: Datentypen von String zu Byte und wieder zurück
 
Beide verschieben die Bits nach links, aber shl schiebt nur 0-Bits von rechts nach.

12345678 shl 4 -> 23456780
12345678 rol 4 -> 23456781

Blup 3. Mai 2017 12:08

AW: Datentypen von String zu Byte und wieder zurück
 
Wenn dann so:
Delphi-Quellcode:
 for i := 0 to 31 do
  begin
    Result := Result shl 1;
    Result := Result or (B shr 31);
    B := B shl 1;

    Result := Result shl 1;
    Result := Result or (A shr 31);
    A := A shl 1;
  end;

himitsu 3. Mai 2017 12:10

AW: Datentypen von String zu Byte und wieder zurück
 
Doch, kann ich, aber :oops:
Delphi-Quellcode:
  for i := 0 to 31 do
  begin
    Result := Result shl 1;
    Result := Result or (B shr 31);
    B := B shl 1;

    Result := Result shl 1;
    Result := Result or (A shr 31);
    A := A shl 1;
  end;
In diesem Fall wird das ja nur benutzt, um nacheinander jedes Bit auszulesen und in diesem Fall kann man einfach auf der anderen Seite auslesen, anstatt im Kreis zu schieben.

[edit]
jupp

[edit2]
Delphi-Quellcode:
  for i := 31 downto 0 do
  begin
    Result := Result shl 1;
    Result := Result or ((B shr i) and $1);

    Result := Result shl 1;
    Result := Result or ((A shr i) and $1);
  end;
Delphi-Quellcode:
  for i := 31 downto 0 do
  begin
    Result := Result shl 2;
    Result := Result or ((B shr (i-1)) and $1) // schiebt SHR bei -1 nach links?
                     or ((A shr i) and $1);
  end;
?

Blup 3. Mai 2017 14:06

AW: Datentypen von String zu Byte und wieder zurück
 
Der zweite Operand ist ein Byte, welches zusätzlich maskiert ist.

1.Operand2.Operand signifikante Bitsentspricht
Byte3a shl (b mod 8)
Word4a shl (b mod 16)
Longword5a shl (b mod 32)
Int646a shl (b mod 64)

Byte(-1) -> 255
(255 mod 32) -> 31

(Longword(a) shr -1) -> (a shr 15)

Das funktioniert also nicht, abgesehen davon müsste die Maske für B $2 sein.

Blup 3. Mai 2017 15:12

AW: Datentypen von String zu Byte und wieder zurück
 
So kann es funktionieren und ist übersichtlich:
Delphi-Quellcode:
 for i := 31 downto 0 do
 begin
   Result := Result shl 1;
   Result := Result or ((B shr i) and $1);
   Result := Result shl 1;
   Result := Result or ((A shr i) and $1);
 end;

Blup 6. Jun 2017 10:43

AW: Datentypen von String zu Byte und wieder zurück
 
Richtig müsste es heißen: (Longword(a) shr -1) -> (a shr 31)


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:37 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz