Autor |
Beitrag |
daywalker0086
      
Beiträge: 243
Delphi 2005 Architect
|
Verfasst: Mo 12.08.13 16:46
Hallo Leute,
ich habe eine Gleitkommazahl z.Bsp. m:=116.0 (Wertebereich 4byte).
Diese soll über die serielle Schnittstelle übertragen werden. Dazu muss ich in diesem Fall den Wert 0x42e80000 übertragen wie hier auch durch umrechnen der Zahl 116.0 als Ergebnis gregstoll.dyndns.org...regstoll/floattohex/.
Die frage ist nun wie ich an die Werte komme also ich gehe davon aus das im Speicher der Variable m genau di eZeichenfolge steht, nur wie komme ich daran?
Grüße Christian
|
|
IhopeonlyReader
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Mo 12.08.13 16:52
ich speicher steht das sicher nicht
dort stehen die einzelnen Bits...
falls du bit für bit lesen willst, kannst du folgendes machen
(cardinal ist z.B. 4 Byte groß)
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| var X: Cardinal; C: Byte; begin For C:=(8*4)-1 downto 0 do begin if Boolean( X and (1 shl C)) then else end; |
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
daywalker0086 
      
Beiträge: 243
Delphi 2005 Architect
|
Verfasst: Mo 12.08.13 17:00
Ich will ja nicht unbedingt bit für bit haben.
Ich habe eine Gleitkommazahl vom typ real, und muss diese Zahl per serielle Schnittstelle übertragen. Der Senderoutine kann ich aber nur einzelne Bytes übergeben. Das heißt Wenn ich eine Real Zahl habe, welche 4 byte groß ist, wie kann ich dann die einzelnen 4 bytes an die serielle Schnittstelle übergeben?
|
|
jfheins
      
Beiträge: 918
Erhaltene Danke: 158
Win 10
VS 2013, VS2015
|
Verfasst: Mo 12.08.13 17:04
Aber sicher steht das im Speicher
Kann deine Senderoutine auch Pointer+Länge? Oder nur Bytearrays?
Besonders einfach ginge es, indem du ein ByteArray mit absolute auf den gleichen Speicher zeigen lässt, wie deine Single-Variable.
Real ist übrigens obsolet. Benutze double oder single stattdessen - in diesem Fall single, da du ja genau vier Bytes haben möchtest.
|
|
IhopeonlyReader
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Mo 12.08.13 17:08
achso
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| var X: Cardinal; B: Array[1..4] of Byte; begin X := $FFFFFFF0; B[1] := X shr (8*3); B[2] := X shr (8*2); B[3] := X shr (8*1); B[4] := Byte(X and 255); end; |
B[1] enthält die ersten 8 Bit, B[2] die n ächsten 8...
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
jaenicke
      
Beiträge: 19326
Erhaltene Danke: 1749
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 12.08.13 17:13
|
|
daywalker0086 
      
Beiträge: 243
Delphi 2005 Architect
|
Verfasst: Mo 12.08.13 17:34
Also mal eine Rückmeldung
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| var X: Cardinal; C: Byte; begin For C:=(8*4)-1 downto 0 do begin if Boolean( X and (1 shl C)) then else end; |
funktioniert nicht da X hier cardinal ist, ich aber ein real Wert habe.
Delphi-Quelltext 1: 2: 3: 4: 5:
| var a: Single; begin a := 116.0; ShowMessage(IntToHex(PInteger(@a)^, 8)); |
Da steht bei mir im Dialog nur 00000000.
EDIT: Ok zeigt das richtige an, hatte a noch als real deklariert.
Also bis jetzt noch keine Lösung.
Hier mal meine Senderoutine damit ihr seht wie ich Daten über die serielle verschicke:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| daten[0]:=$06; daten[1]:=$10; daten[2]:=$06; daten[3]:=wr_anzahl; daten[4]:=(sw1); daten[5]:=maske_berechnen(1); for i:=0 to 5 do begin prog_finish := 0; sendstr:=sendstr+inttohex(daten[i],2); end; serialp1.SendString(hextostr(sendstr)); |
Die Komponente ist SerialNG von DomIS.
www.domis.de/cms/ind...amp;mid=3&ceid=7
|
|
daywalker0086 
      
Beiträge: 243
Delphi 2005 Architect
|
Verfasst: Mo 12.08.13 17:48
So hab es jetzt so gelöst:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| procedure TForm1.Button5Click(Sender: TObject); var a: Single; wert:string; wert_byte: array[1..4] of string; begin a := 116.5; wert:= IntToHex(PInteger(@a)^, 2); wert_byte[1]:= copy(wert,0,2); showmessage(wert_byte[1]); wert_byte[2]:=copy(wert,3,2); showmessage(wert_byte[2]); wert_byte[3]:= copy(wert,5,2); showmessage(wert_byte[3]); wert_byte[4]:= copy(wert,7,2); showmessage(wert_byte[4]);
end; |
Jetzt hab ich im Array wert_byte jedes einzelne Byte drin und kann es so über die serielle Schnittstelle ausgeben.
Jetzt die Frage: gehts noch eleganter/einfacher?
|
|
MeierZwoo
      
Beiträge: 94
Erhaltene Danke: 11
Win 7, DOS5
Delphi 2007 Architect, BP7/TP5, LISP, PS
|
Verfasst: Mo 12.08.13 18:10
Mich würde grade bei Gleitkommatypen als erstes interessieren, ob die Gegenseite mit den Bytes überhaupt etwas anfangen kann. Auf der Empfängerseite kann ja ein ganz anderes Programm, durch einen völlig anderen Compiler oder auch nur einer anderen Compiler-Version erstellt die Bytes lesen und sich wundern, was das soll.
Denn die Gegenseite muß ja den exakt selben Datentyp verwenden, um die Bytes dann wieder in der richtigen Form in den Speicher zu schreiben ... und zu interpretieren. Und da kann schon ein Versionswechsel, oder eine andere Plattform (32bit, 64bit) alles zunichte machen.
Deshalb ist bei DFÜ der Normalfall, die Werte in Strings umzuwandeln und so zu senden ... es sei denn, es handelt sich auf exakt aufeinander abgestimmte Hardware mit abgestimmter Firm- und Software, wie z.B. im Meß- und Regelwesen.
|
|
IhopeonlyReader
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Mo 12.08.13 18:41
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
IhopeonlyReader
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Mo 12.08.13 18:46
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
jaenicke
      
Beiträge: 19326
Erhaltene Danke: 1749
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 12.08.13 20:43
Warum um alles in der Welt friemelst du da mit Strings herum, wenn du gar keinen String schicken willst? Die genannte Komponente hat den Befehl SendData... Delphi-Quelltext 1: 2: 3: 4:
| var a: Single;
serialp1.SendData(@a, SizeOf(a)); | Und um die Bytes alle zu schicken könntest du ein array of Byte benutzen.
|
|
mandras
      
Beiträge: 433
Erhaltene Danke: 107
Win 10
Delphi 6 Prof, Delphi 10.4 Prof
|
Verfasst: Mo 12.08.13 21:31
jaenickes Methode ist die kürzeste,
verständlicher ist vielleicht folgendes wenn man doch auf einzelne Bytes zugreifen muß:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| procedure TForm1.Button1Click(Sender: TObject); var a:single; b:array[0..3] of byte absolute a; begin a:=116; end; |
|
|
jasocul
      
Beiträge: 6395
Erhaltene Danke: 149
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Di 13.08.13 08:18
Und wer noch weiß, was ein Record ist, kann es auch über einen varianten Record machen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| var a : record case Boolean of True : (s : Single); False : (b : Array[0..3] of Byte); end; ... a.s := 116.5; |
Dann steht in a.b Byte-Darstellung.
Aber ich würde auch die Variante von Jaenicke nehmen. 
|
|