Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Mal wieder HexToFloat (https://www.delphipraxis.net/193216-mal-wieder-hextofloat.html)

echitna 6. Jul 2017 09:19

Mal wieder HexToFloat
 
Hallo,

ich habe folgendes Problem:
Ich bekomme über eine Schnittstelle einen String, der eine Hexadezimalzahl repräsentiert (4 Zeichen lang), also z.B. 'FF E4' oder '00 03'.
Dieser String muss jetzt in einen Gleitkommawert umgewandelt werden. Ich habe eine Funktion dafür, die den Wert in binärstring
umwandelt so dass dann die Mantisse und der Exponent ausgerechnet werden kann. Die Funktion gibt dann das Ergebnis der Rechnung result := mantisse * power(2,exponent) aus. Das Problem ist jetzt, dass ich mit der Funktion eine normalisierte Zahl (also z.B. 9.17963e-41) als Ergebnis bekomme, ich hätte aber gerne eine 'normale' Kommazahl (also z.B. 0,00000917).
Hat jemand eine Idee wie man das hinkriegt, oder gibt es vielleicht sogar noch eine einfachere Methode einen Hex-String in eine Kommazahl zu konvertieren?

(Tante Google hat mir leider auch nicht geholfen)

gammatester 6. Jul 2017 09:33

AW: Mal wieder HexToFloat
 
Was soll das für ein Format sein? 4 Hex-Zeichen sind 16-Bit, das ist ein Format, das ungeöhnlich ist (single hat 32-Bit). Ohne Dokumentation des internen Aufbaus des 16-Bit-Wortes kann man wohl wenig sagen oder helfen.

himitsu 6. Jul 2017 09:34

AW: Mal wieder HexToFloat
 
Nein, du bekommst eine unformatierten "binären" Wert.

Wie du diesen Wert dann darstellst, also wieder in einen String umwandelst, ist dir überlassen.
z.B. Delphi-Referenz durchsuchenFormat oder Delphi-Referenz durchsuchenFormatFloat

Neutral General 6. Jul 2017 09:38

AW: Mal wieder HexToFloat
 
Du kannst folgendes machen:
Delphi-Quellcode:
function HexToSingle(hex: String): Single;
var tmp: Cardinal;
begin
  tmp := StrToInt('$' + hex);
  Move(tmp, Result, SizeOf(Cardinal));
end;

var f: Single;
begin
  f := HexToSingle('FFE4');
  Caption := FloatToStr(f);
end;
Prinzipiell kannst du mit FloatToStrF oder Format die Zahl (wenn du sie als String ausgeben willst) auf X Nachkommastellen formatieren.
Hinweis: 9.17963e-41 ist NICHT 0,00000917. Die Darstellung "9.17963e-41" wird benutzt, weil die Zahl ausgeschrieben so aussehen würde:

0,0000000000000000000000000000000000000000917963

gammatester 6. Jul 2017 10:08

AW: Mal wieder HexToFloat
 
Zitat:

Zitat von Neutral General (Beitrag 1376104)
Du kannst folgendes machen:
Delphi-Quellcode:
function HexToSingle(hex: String): Single;
var tmp: Cardinal;
begin
  tmp := StrToInt('$' + hex);
  Move(tmp, Result, SizeOf(Cardinal));
end;

Ich glaube nicht, daß das so gewollt ist. Das Ergebnis ist immer ein denormalisiertes Single. Außerdem kann man so keine negativen Zahlen erhalten. Wie wäre es mit
Delphi-Quellcode:
function HexToSingle(hex: String): Single;
var tmp: smallint;
begin
  tmp := StrToInt('$' + hex);
  Result := tmp;
end;

Neutral General 6. Jul 2017 12:07

AW: Mal wieder HexToFloat
 
Zitat:

Zitat von gammatester (Beitrag 1376113)
Wie wäre es mit
Delphi-Quellcode:
function HexToSingle(hex: String): Single;
var tmp: smallint;
begin
  tmp := StrToInt('$' + hex);
  Result := tmp;
end;

Eh ja, so gehen alle Nachkommastellen verloren und die Zahl ist komplett falsch.

gammatester 6. Jul 2017 13:27

AW: Mal wieder HexToFloat
 
Zitat:

Zitat von Neutral General (Beitrag 1376133)
Eh ja, so gehen alle Nachkommastellen verloren und die Zahl ist komplett falsch.

Welche Nachkommastellen? Wie schon gesagt: Solange keine Auskunft über die Bedeutung der 4 Hex-Zeichen gemacht wird (zB: nimm den Integerwert/100), sehe ich erst einmal keine Nachkomnastellen. Deine Nachkommastellen sind doch völlig sinnlos, wenn man bedenkt, daß die kleinste normalisierte Singlezahl ca 1.17549e-38 ist und damit ca 128 mal größer(!) als 9.17963e-41. Und das gilt für jede vierstellige Hexeingabe.

Neutral General 6. Jul 2017 13:35

AW: Mal wieder HexToFloat
 
Vielleicht waren es auch nur schlechte (zu kurze) Beispiele?
Ich habe es so interpretiert dass er/sie "echte" Floats als Hex-String erhält.
Seine/Ihre Vorgehensweise diese umzuwandeln und dass mein Code das gleiche Ergebnis erzielt scheint das zu bestätigen.

Dass die Ergebnisse nicht so aussehen als wären sie gewollt stimmt wohl.
Es ist wahrscheinlich nicht auszuschließen dass er/sie selbst nicht genau weiß diese Hex-Strings darstellen und wie sie decodiert werden müssen.

Von daher: Wir brauchen mehr Infos.

HolgerX 6. Jul 2017 13:45

AW: Mal wieder HexToFloat
 
Hmm

Also ich vermute, dass es sich um HalfFloat oder auch Float16 handelt.
Diese haben nur 2 Bytes und werden in Hex eben so dargestellt.

Jedoch müssen diese in Delphi umgerechnet werden auf z.B. single.

Hierbei wird daraus (glaube ich) zunächst ein WORD (mit StrToInt('$'+AString)) gemacht und dieses dann nach Single konvertiert.

Beispiele habe ich keine...

Neutral General 6. Jul 2017 13:50

AW: Mal wieder HexToFloat
 
Zitat:

Zitat von HolgerX (Beitrag 1376144)
Hierbei wird daraus (glaube ich) zunächst ein WORD (mit StrToInt('$'+AString)) gemacht und dieses dann nach Single konvertiert.

Beispiele habe ich keine...

Das ist was mein Code weiter oben macht. Aber mit Cardinal, statt Word, was aber unterm Strich keinen Unterschied macht.
Das Problem ist, dass ein 16-Bit Float in einem 32-Float nicht den gleichen Wert hat.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:40 Uhr.
Seite 1 von 3  1 23      

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